前后端鉴权一直是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(); } } ); }};复制代码
全部代码: