前后端鉴权一直是web开发的常见问题,今天就用一个demo来总结下常见的session和token鉴权方式。
session鉴权
我们用代码来说明。
session-cookie鉴权关键的一点是在服务端保存session,我们这边用redis进行保存,然后给客户端发送cookie。当客户端访问服务端时,携带cookie,而这cookie就是redis保存session的key,能拿到对应的session就证明客户端有权限访问服务端的api,否在就是非法访从而拒绝,要求登录验证身份后才能发起访问。
而在koa2中实现session的存取鉴定,我们可以把该过程封装成一个中间件,然后在路由请求响应前响应就行了。
具体的可以看代码和其中的注释。
module.exports = function (opts = {}) {
opts.key = opts.key || "cookieKey";
return async function (ctx, next) {
let cookie = ctx.cookies.get(opts.key, opts);
// cookie是否存在
if (cookie) {
// 删除cookie,为了在下一步重置cookie的时间
ctx.cookies.set(opts.key, cookie, {maxAge: -1});
// 如果session存在,删除redis的session为了在下一步重置session的时间
ctx.session = await opts.store.get(cookie);
if(ctx.session) {
// 删除redis的值
opts.store.destroy(cookie);
}
} else {
ctx.session = undefined
}
await next();
// 有权限的操作或者登录
if (ctx.session) {
// 更新session时间或者存放新的session
let newCookie = await opts.store.set(ctx.session, Object.assign({}, opts, {sid: cookie}));
// 更新cookie的时间
ctx.cookies.set(opts.key, newCookie, opts);
}
}};复制代码
token鉴权
token的话,只要在登录的时候生成token返回客户端,然后客户端请求时携带token即可完成验证操作。在koa2中使用jsonwebtoken插件进行token的生成和验证。具体可以看下代码。
const jwt = require('jsonwebtoken');
const baseConfig = require('../config/basice.js');复制代码
module.exports.createToken = function (userName) {
return jwt.sign(
{userName},
baseConfig.jwtSecretKey,
{expiresIn: baseConfig.expiresIn}
);
};
module.exports.checkToken = function (ctx, next) {
let token = ctx.headers['client-token'];
if (!token) {
ctx.body = {
success: false,
error: {
code: 401,
message: 'token不能为空'
}
};
} else {
jwt.verify(token, baseConfig.jwtSecretKey, async function (err) {
if (err) {
let message;
if (err.name === 'TokenExpiredError') {
message = 'token已过期';
} else {
message = 'token无效';
}
ctx.body = {
success: false,
error: {
code: 401,
message
}
};
} else {
return await next();
}
}
);
}
};复制代码