npm-package/auth/index.js

131 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
const crypto = require('crypto');
const Redis = require('ioredis');
function AuthToken(redisdb, expiresSeconds) {
this.tokenDB = redisdb;
this.defaultExpiresSeconds = expiresSeconds;
}
// 创建一条Redis记录并生成Token
AuthToken.prototype.genToken = async function ({ userData, userApp }) {
// 生成系统内部的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,
apps: {},
createts: Math.floor(Date.now() / 1000),
ttl: this.defaultExpiresSeconds
};
tokenData.apps[userApp.appid] = userApp;
await this.tokenDB.set(userToken, JSON.stringify(tokenData), 'EX', this.defaultExpiresSeconds);
return userToken;
};
// 更新Token数据
AuthToken.prototype.update = async function (userToken, { userData, userApp, ttl }) {
let tokenData = await this.tokenDB.get(userToken).then(function (data) {
return JSON.parse(data);
});
if (tokenData) {
if (userData) tokenData.userData = userData;
if (userApp) tokenData.apps[userApp.appid] = userApp;
if (ttl) tokenData.ttl = ttl;
await this.tokenDB.set(userToken, JSON.stringify(tokenData), 'EX', this.defaultExpiresSeconds);
return tokenData;
}
return null
};
// 删除Token记录
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);
}
};
// 检查Token是否存在
AuthToken.prototype.checkToken = async function (userToken, updateExpire = true) {
let tokenData = await this.tokenDB.get(userToken).then(function (data) {
return JSON.parse(data);
});
// token不存在
if (!tokenData) {
return null;
}
if (updateExpire) {
this.tokenDB.expires(userToken, tokenData.ttl)
}
return tokenData;
};
// 获取Token数据
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;
};
AuthToken.prototype.checkTokenKoaRequest = async function (ctx, next) {
let token = ctx.request.body.token
if (!token) token = ctx.header['authorization']
if (!token) token = ctx.header['token']
if (!token) {
ctx.body = { code: 401, msg: 'Need user token.', data: {} };
return;
}
let tokenData = await this.checkToken(token);
if (!tokenData) {
ctx.body = { code: 401, msg: 'User token not exist.', data: {} };
return;
}
ctx.userData = tokenData.userData;
let appid = ctx.request.body.appid;
if (!appid) appid = ctx.header['appid'];
if (appid) ctx.userApp = tokenData.apps[appid];
return next();
};
/*
AuthToken.prototype.checkTokenKoaRequestByAgent = async function (ctx, next) {
return this.checkTokenKoaRequest(ctx, ctx.userAgent.source, true, next);
};
*/
let tokenInstance = null;
module.exports = function getTokenInstance(redisdb) {
if (!tokenInstance) {
tokenInstance = new AuthToken(redisdb);
}
return tokenInstance;
};