大多数的项目中,我们都会使用token进行验证处理,然而,在实际操作中,总会遇到由于token到了过期时间的临界点,而导致操作失败,从而需要再重新获取token重新操作一遍。
本文章给出了一个解决方案,仅供大家参考:
后台获取token后,先解析token是否合法,合法再获取它的过期时间点,然后通过过期时间和当前系统时间的对比得出一个时间差,最后再判断这个时间差是否在你允许的范围内,允许则过,不允许则401抛token无效。(允许的时候,结合你项目的场景刷新token返回给前端)具体参考下面核心代码:
npm install koa --save-dev npm install koa-jwt --save-dev npm install jsonwebtoken --save-dev npm install util --save-dev
const Koa = require('koa'); const jwtKoa = require('koa-jwt');//jwt认证与授权 const jwt = require('jsonwebtoken');//jwt认证与授权 const util = require('util') const verify = util.promisify(jwt.verify) // 解密 var app = new Koa(); const secret_admin = 'admin';//token秘钥key /** * 先进行token失效401处理 */ app.use(function(ctx, next){ return next().catch((err) => { if (401 == err.status) { ctx.status = 401; // ctx.body = 'Protected resource, use Authorization header to get access\n'; ctx.body = 'Unauthorized Token'; } else { throw err; } }); }); /** * 判断token是否过期(过期则判断是否在10分钟之内,如果在10分钟之内发送请求则给用户重新刷新token) */ app.use(async (ctx, next) => { //获取生成token时的过期时间,判断是否在允许过期延迟时间范围内,如果是则重新生成token返回,否则报错#begin var payload = {}; //防止token不传或token前缀不符 if(!ctx.header.authorization || ctx.header.authorization.indexOf('Bearer ') == -1){ ctx.throw(401, 'Bad Authorization header format. Format is "Authorization: Bearer"'); } try{ payload = await verify(ctx.header.authorization.split(' ')[1], secret_admin); }catch(err){ console.log(err.message,new Date(err.expiredAt).getTime()); if(err.message === 'jwt expired'){ payload.exp = parseInt(new Date(err.expiredAt).getTime()/1000); }else{ throw err; } } if(payload && payload.exp){ var allowTime = parseInt(new Date().getTime()/1000) - parseInt(payload.exp); if( allowTime > -1 && allowTime <= 600 || allowTime < 0){ await next(); }else{ ctx.throw(401, 'Bad Authorization header format. Format is "Authorization: Bearer"'); } }else{ ctx.throw(401, 'Bad Authorization header format. Format is "Authorization: Bearer"'); } //原方法判断token是否过期,无法对正在进行操作进行包容扩展 // app.use(jwtKoa({secret: secret_admin}).unless({ // path: [ //数组中的路径不需要通过jwt验证 // /^\/login.json/, // ] // })); });