登录:发送账户密码到后端
node端:
1.判断是否存在此用户
2.通过账户密码校验用户
3.获得账户信息中的是否允许登录信息
4.通过以上之后,使用id进行jwt加密,生成拥有时效的token信息(保存于session中)
5.成功返回:用户信息(权限信息----->进行页面和路由的权限设计)、token
登录成功------------->前端将此token携带于每次请求中(需要token的每次请求中):判断登录+鉴权的中间件
1.登录成功之后,获得token信息,写入cookie(注意跨域cookie的问题)、或者写入请求头
2.携带token请求,后端解析拿到token,检查是不是和session保存的一致(这点可不用)
3.解密jwt,是否有效
4.解密得到id,使用此id查询账户
5.能否得到用户,且检查用户里是否允许登录的信息
6.检验用户是否有此项请求权限
7.通过以上,,,,才进入请求内容。
权限管理代码,中间件 middleware/checkToken.js
'use strict'
module.exports = options => {
return async function checkTokenIsLogin(ctx, next) {
const cookieToken = ctx.helper.cookieToJson(ctx.request.header.cookie);
const token = cookieToken.userToken;
if (!token) {
ctx.body = ctx.response.ServerResponse.needLogin();
return;
}
// 检查是否允许登录
const jwtToken = ctx.helper.verifyToken(token, options.key);
if (!jwtToken) {
ctx.body = ctx.response.ServerResponse.needLogin();
return;
}
const { id } = ctx.helper.verifyToken(token, options.key);
const user = await ctx.service.user.getUserById(id);
if (!user.allowLogin) {
ctx.body = ctx.response.ServerResponse.canNotLogin();
return;
}
let isRole = '';
Object.keys(ctx.helper.roleObj).forEach(u => {
if (ctx.helper.pathMatchRegexp(u, ctx.request.url)) {
isRole = ctx.helper.roleObj[u];
}
});
if (!user.role.includes(isRole)) {
ctx.body = ctx.response.ServerResponse.noAuth();
return;
}
// 更新token时效
ctx.cookies.set('userToken', ctx.helper.createToken(id, options.key));
await next();
};
};