教程 koa tutorial

JWT 鉴权

JWT(JSON Web Token)是一种基于 Token 的认证方式,通常用于客户端和服务器之间传递信息,常用于 Web 应用的用户身份认证。它是一种自包含的、安全的认证方法,广泛用于 API 认证、单点登录(SSO)等场景。

为什么使用 JWT?

  • 无状态认证:JWT 是自包含的,可以存储用户的身份信息和权限,不需要在服务器存储会话信息。
  • 跨平台支持:JWT 作为一种标准的认证机制,支持多平台、多语言实现。
  • 安全性:JWT 通过签名和加密保护数据的完整性和机密性。
  • 方便扩展:JWT 可以灵活地扩展其他自定义数据,如用户权限、角色等。

JWT 的结构

JWT 由三个部分组成:

  1. 头部(Header):通常包括类型(JWT)和使用的签名算法(如 HMAC SHA256 或 RSA)。
  2. 有效载荷(Payload):包含用户信息以及一些元数据。有效载荷是可以解码的,但不加密,因此不应存储敏感数据。
  3. 签名(Signature):用来验证消息是否被篡改,使用头部中的算法和密钥对头部和有效载荷进行签名。

JWT 的结构格式如下:

代码

Header.Payload.Signature

`

在 Koa 中实现 JWT 鉴权

安装相关依赖

首先,我们需要安装 JWT 相关的依赖库 jsonwebtoken:

bash
npm install jsonwebtoken

`

生成 JWT Token

在用户登录时,我们会生成一个 JWT Token,并将其返回给客户端。客户端可以在后续请求中携带该 Token。

js
// auth.js
const jwt = require('jsonwebtoken');

const SECRET_KEY = 'your-secret-key'; // 替换为强随机密钥

// 登录时生成 JWT Token
const generateToken = (user) => {
  const payload = {
    id: user.id,
    username: user.username,
  };

  // 设置 Token 的有效期
  const options = { expiresIn: '1h' };

  // 使用密钥和算法生成 Token
  return jwt.sign(payload, SECRET_KEY, options);
};

module.exports = { generateToken };

校验 JWT Token

在后续的请求中,客户端需要将 Token 放在请求头中。我们通过中间件来验证 Token 是否有效。

js
// authMiddleware.js
const jwt = require('jsonwebtoken');
const SECRET_KEY = 'your-secret-key'; // 替换为强随机密钥

// 校验 JWT Token 中间件
const verifyToken = (ctx, next) => {
  const token = ctx.headers['authorization'];

  if (!token) {
    ctx.status = 401;
    ctx.body = { message: 'Token is required' };
    return;
  }

  try {
    // 校验 Token 是否有效
    const decoded = jwt.verify(token, SECRET_KEY);

    // 将用户信息存储在 ctx.state 中,供后续使用
    ctx.state.user = decoded;
    return next();
  } catch (error) {
    ctx.status = 401;
    ctx.body = { message: 'Invalid or expired token' };
  }
};

module.exports = { verifyToken };

保护路由

使用 JWT 校验中间件来保护需要身份认证的路由。例如,只有经过认证的用户才能访问某些 API 接口。

js
// user.js
const Router = require('koa-router');
const { verifyToken } = require('./authMiddleware');
const router = new Router();

// 需要身份认证的路由
router.get('/profile', verifyToken, async (ctx) => {
  const user = ctx.state.user; // 获取用户信息

  ctx.body = { message: 'Profile data', user };
});

module.exports = router;

完整示例

以下是一个完整的 Koa JWT 鉴权示例,包含生成 Token、校验 Token 和保护路由的步骤。

js
const Koa = require('koa');
const Router = require('koa-router');
const jwt = require('jsonwebtoken');
const { generateToken } = require('./auth');
const { verifyToken } = require('./authMiddleware');

const app = new Koa();
const router = new Router();

// 用户登录,生成 JWT Token
router.post('/login', async (ctx) => {
  const { username, password } = ctx.request.body;

  // 简单的用户验证逻辑
  if (username === 'user' && password === 'password') {
    const user = { id: 1, username };
    const token = generateToken(user);
    ctx.body = { token };
  } else {
    ctx.status = 401;
    ctx.body = { message: 'Invalid username or password' };
  }
});

// 需要身份认证的保护路由
router.get('/profile', verifyToken, async (ctx) => {
  const user = ctx.state.user; // 获取经过验证的用户信息
  ctx.body = { message: 'Profile data', user };
});

app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
  console.log('Server running on port 3000');
});

总结

通过上述步骤,我们在 Koa 中实现了基于 JWT 的身份认证和授权。JWT 是一种轻量级的认证机制,适用于无状态的应用,能够有效地进行用户认证和授权。通过在 Koa 中实现生成 Token、验证 Token 和保护路由,我们能够为 Web 应用提供安全的身份验证功能。