在 RESTful API 设计中使用 JSON Web Token(JWT) 的优缺点分析
RESTful API 设计中使用 JSON Web Token (JWT) 是一种流行的认证和授权方法。它可以让你在你的应用程序和服务中轻松实现用户身份验证和访问控制。本文将探讨使用 JWT 的优缺点,并提供一些示例代码和指导意义。
什么是 JWT?
JSON Web Token (JWT) 是一个开放标准 (RFC 7519),它可以安全地将信息传输为 JSON 格式的对象。 JWT 包含三个部分:
Header:描述 JWT 的元数据,包含加密算法等信息。
Payload:包含应用程序定义的声明(claims)。这些声明描述了关于 JWT 的实体(通常是用户)和其他数据的信息。
Signature:使用加密算法生成的元数据和有效负载的签名。
如何工作?
JWT 的使用场景通常是这样的,当用户在进行身份验证后,服务器会生成一个 JSON 对象并将其用作 JWT 的有效载荷。该有效载荷包含访问令牌和附加的声明。服务器签署有效载荷后返回 JWT,客户端在随后的请求中将该标记作为 Authorization 头的 Authorization:Bearer <jwt> 的一部分发送回服务器。服务器将解析 JWT 并使用其声明执行访问控制。
优点
比较轻量级
JWT 可以在客户端和服务器之间传输,并且在不增加大量网络负载的情况下通过浏览器的 Cookie 或本地存储进行存储。
提供安全性
由于 JWT 中包含一个签名,所以在客户端-服务器之间传输期间,不会被篡改。服务器在接收 JWT 时对其进行验证。此外,JWT 还可以使用加密算法进行强制加密,以保护其中的数据。
无需在服务器记录会话信息
由于 JWT 可以自包含,所以服务器无需记录会话信息。这可以减轻服务器的负担。
缺点
JWT 无法使其过期失效
一旦 JWT 被颁发,它将一直有效直到过期或被吊销。如果 JWT 被使用恶意人士得到,他们就可以使用 JWT 访问特定的服务并破坏访问控制。因此,为了减少此风险,JWT 过期时间需要小心分配。
存在传输风险
尽管 JWT 的自我包含性使其更加轻巧,但在传输期间其内容仍然暴露在客户端代码中。恶意人士可以窃取 JWT 并使用其中的信息访问受保护的服务。
结论
JWT 是一种非常流行的认证和授权机制,它可以使您轻松实现应用程序中的登录和授权。但是,JWT 还有它的缺点,例如时间过期和传输风险,开发人员应该在实施之前认真考虑。因此,使用 JWT 的最佳方式是将其与其他安全标准和最佳实践结合使用,以实现强大的身份验证和访问控制。
示例代码
//创建JWT的函数 function createJWT(user) { const header = { "alg": "HS256", // algorithm used to sign token, should be a secure one "typ": "jwt" };
const claims = { "userId": user.userId, // user's id from database "username": user.username, // user's name from database "email": user.email, // user's email from database "exp": Math.floor(Date.now() / 1000) + 60 * 60 // token expiration in seconds };
const signature = sign(header, claims); // sign token
const jwt = ${encode(header)}.${encode(claims)}.${signature}
; // combine token parts
return jwt; }
//解析JWT的函数 function verifyJWT(jwt) { const [headerB64, claimsB64, signature] = jwt.split("."); const header = decode(headerB64); const claims = decode(claimsB64);
if(signature !== sign(header, claims)) { throw new Error("Invalid token signature!"); }
if(claims.exp <= Math.floor(Date.now() / 1000)) { throw new Error("Token expired!"); }
return { userId: claims.userId, username: claims.username, email: claims.email }; }
// 使用JWT进行身份验证的Express中间件 function authMiddleware(req, res, next) { const authHeader = req.headers.authorization;
if(authHeader) { const token = authHeader.split(" ")[1];
try { const user = verifyJWT(token); req.user = user; next(); } catch (error) { res.status(401).json({ message: "Invalid token!" }); }
} else { res.status(401).json({ message: "Token required!" }); } }
// 使用authMiddleware保护路由 app.get("/user", authMiddleware, (req, res) => { const user = req.user; res.json(user); });
//返回JWT给客户端 app.post("/login", (req, res) => { const { username, password } = req.body;
const user = db.find(user => user.username === username && user.password === password);
if(user) { const jwt = createJWT(user); res.json({ jwt }); } else { res.status(401).json({ message: "Invalid credentials!" }); } });
注释:上面的示例代码使用 Node.js 和 Express。createJWT
创建 JWT,verifyJWT
验证 JWT 的签名和有效性,authMiddleware
中间件检查 JWT 是否存在并验证其有效性。最后,路由需要身份验证。
参考资料
https://www.adrianprieto.com/authentication-in-restful-api-with-jwt/
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6748386093696b0268eb2407