Node/Koa2[24]: JWT
·
Yin灏
JWT
-
jwt - json web token
-
用户认证成功之后,server 端返回一个加密的 token 给客户端
-
客户端后续每次请求都带 token,以示当前的用户身份
模拟登录
routes/user.js
//...
const jwt = require("jsonwebtoken");
const { SECRET } = require("../conf/constants");
//...
const util = require("util");
const verify = util.promisify(jwt.verify);
//...
router.post("/login", async (ctx, next) => {
const { userName, password } = ctx.request.body;
let userInfo;
let token;
if (userName === "zhangsan" && password === "abc") {
userInfo = {
userId: 1,
userName: "zhangsan",
nickName: "张三",
gender: 1,
};
}
// 加密
if (userInfo) {
token = jwt.sign(userInfo, SECRET, {
expiresIn: "1h",
});
}
if (userInfo == null) {
ctx.body = {
errnno: -1,
msg: "登录失败",
};
return;
}
ctx.body = {
error: 0,
data: token,
};
});
//...
// 获取用户信息
router.get("/getUserInfo", async (ctx, next) => {
const token = ctx.header.authorization;
try {
const payload = await verify(token.split(" ")[1], SECRET);
ctx.body = {
errno: 0,
userInfo: payload,
};
} catch (ex) {
ctx.body = {
errno: -1,
msg: "verify token failed",
};
}
});
数据加密
- 安装依赖
npm i koa-jwt --save
npm i jsonwebtoken --save #加密工具
- 引用
app.js
const { SECRET } = require("./conf/constants");
const jwtKoa = require("koa-jwt");
// 需要在路由注册之前引用
app.use(
jwtKoa({
secret: SECRET,
}).unless({
path: [/^\/users\/login/], // 自定义那些目录忽略 jwt 验证
})
);
- 配置
conf/constants.js
module.exports = {
SECRET: "UsdU*975_+qwe",
};
jwt vs session
-
为了解决:登录 & 存储登录用户的信息
-
jwt 用户信息加密存储在客户端,不依赖 cookie,可跨域
-
session 用户信息存储在服务端,依赖 cookie,默认不可跨域
-
一般情况下,两者都能满足,大型系统中两者可共用
-
jwt 更适合于服务节点较多,跨域比较多的系统
-
session 更适合统一的 web 服务,server 要严格管理用户信息