'use strict'; const crypto = require('crypto'); const Redis = require('ioredis'); function AuthToken(redisdb) { this.tokenDB = redisdb; } AuthToken.prototype.genToken = async function(userData, expiresSeconds) { // 生成系统内部的user token let hash = crypto.createHash('md5'); hash.update(JSON.stringify(userData) + Date() + Math.random()); let userToken = hash.digest('hex'); // 缓存到redis let tokenData = { userData: userData, expires: {ttl: expiresSeconds, ts: Math.floor(Date.now() / 1000)} }; await this.tokenDB.set(userToken, JSON.stringify(tokenData), 'EX', expiresSeconds); return userToken; }; AuthToken.prototype.delToken = async function (userToken) { let tokenData = await this.tokenDB.get(userToken).then(function(data) { return JSON.parse(data); }); if (tokenData) { this.tokenDB.del(userToken); } }; AuthToken.prototype.checkToken = async function (userToken) { let tokenData = await this.tokenDB.get(userToken).then(function(data) { return JSON.parse(data); }); // token不存在 if (!tokenData) { return false; } // tokenData.expires.ts = Math.floor(Date.now() / 1000); this.tokenDB.set(userToken, JSON.stringify(tokenData), 'EX', tokenData.expires.ttl); return true; }; AuthToken.prototype.checkTokenKoaRequest = async function (ctx, next) { if (!ctx.request.body.token) { ctx.body = { result: 'fail', error: { code: 401, msg: 'Need user token.' }, data: {} }; return; } let tokenData = await this.tokenDB.get(ctx.request.body.token).then(function(data) { return JSON.parse(data); }); if (!tokenData) { ctx.body = { result: 'fail', error: { code: 401, msg: 'User token error.' }, data: {} }; return; } ctx.userData = tokenData.userData; // tokenData.expires.ts = Math.floor(Date.now() / 1000); this.tokenDB.set(ctx.request.body.token, JSON.stringify(tokenData), 'EX', tokenData.expires.ttl); return next(); }; AuthToken.prototype.checkTokenKoaRequestPost = async function (ctx, next) { if (ctx.req.method === 'POST') { return this.checkTokenKoaRequest(ctx, next); } next(); }; AuthToken.prototype.getTokenData = async function (userToken) { let tokenData = await this.tokenDB.get(userToken).then(function(data) { return JSON.parse(data); }); // token不存在 if (!tokenData) { return null; } return tokenData; }; let tokenInstance = null; module.exports = function getTokenInstance(redisdb) { if (!tokenInstance) { tokenInstance = new AuthToken(redisdb); } return tokenInstance; };