JWT 鉴权
JWT(JSON Web Token)是一种基于 Token 的认证方式,通常用于客户端和服务器之间传递信息,常用于 Web 应用的用户身份认证。它是一种自包含的、安全的认证方法,广泛用于 API 认证、单点登录(SSO)等场景。
为什么使用 JWT?
- 无状态认证:JWT 是自包含的,可以存储用户的身份信息和权限,不需要在服务器存储会话信息。
- 跨平台支持:JWT 作为一种标准的认证机制,支持多平台、多语言实现。
- 安全性:JWT 通过签名和加密保护数据的完整性和机密性。
- 方便扩展:JWT 可以灵活地扩展其他自定义数据,如用户权限、角色等。
JWT 的结构
JWT 由三个部分组成:
- 头部(Header):通常包括类型(JWT)和使用的签名算法(如 HMAC SHA256 或 RSA)。
- 有效载荷(Payload):包含用户信息以及一些元数据。有效载荷是可以解码的,但不加密,因此不应存储敏感数据。
- 签名(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 应用提供安全的身份验证功能。