refactor: auth version to 1.3.4

token data more sample
This commit is contained in:
like 2020-12-04 20:21:12 +08:00
parent acbaa67c22
commit 51864c7d5b
5 changed files with 1817 additions and 76 deletions

View File

@ -1,53 +1,68 @@
'use strict'; "use strict";
const crypto = require('crypto'); const crypto = require("crypto");
const Redis = require('ioredis'); const Redis = require("ioredis");
function AuthToken(redisdb, expiresSeconds) { function AuthToken(redisdb, defaultExpiresSeconds) {
this.tokenDB = redisdb; this.tokenDB = redisdb;
this.defaultExpiresSeconds = expiresSeconds; this.defaultExpiresSeconds = defaultExpiresSeconds;
} }
// 创建一条Redis记录并生成Token // 创建一条Redis记录并生成Token
AuthToken.prototype.genToken = async function ({ userData, userApp }) { AuthToken.prototype.gen = async function ({ uid, appid }) {
let userToken = '';
try {
// 生成系统内部的user token // 生成系统内部的user token
let hash = crypto.createHash('md5'); let hash = crypto.createHash("md5");
hash.update(JSON.stringify(userData) + Date() + Math.random()); hash.update(uid + Date() + Math.random());
let userToken = hash.digest('hex'); userToken = hash.digest("hex");
// 缓存到redis // 缓存到redis
let tokenData = { let tokenData = {
userData: userData, uid,
apps: {}, appids: [appid],
createts: Math.floor(Date.now() / 1000), ts: Math.floor(Date.now() / 1000),
ttl: this.defaultExpiresSeconds ttl: this.defaultExpiresSeconds,
}; };
tokenData.apps[userApp.appid] = userApp;
await this.tokenDB.set(userToken, JSON.stringify(tokenData), 'EX', this.defaultExpiresSeconds); let ret = await this.tokenDB.set(userToken, JSON.stringify(tokenData), "EX", this.defaultExpiresSeconds);
if (ret != 'OK') {
console.log('set token to redis db fail:' + ret);
}
} catch (err) {
console.log(err)
}
return userToken; return userToken;
}; };
// 更新Token数据 // 更新Token数据
AuthToken.prototype.update = async function (userToken, { userData, userApp, ttl }) { AuthToken.prototype.update = async function (userToken, { appid }) {
try {
let tokenData = await this.tokenDB.get(userToken).then(function (data) { let tokenData = await this.tokenDB.get(userToken).then(function (data) {
return JSON.parse(data); return JSON.parse(data);
}); });
if (tokenData) { if (tokenData) {
if (userData) tokenData.userData = userData; if (appid && !(appid in tokenData.appids)) {
if (userApp) tokenData.apps[userApp.appid] = userApp; tokenData.appids.push(appid);
if (ttl) tokenData.ttl = ttl; }
await this.tokenDB.set(userToken, JSON.stringify(tokenData), 'EX', this.defaultExpiresSeconds); let ret = await this.tokenDB.set(userToken, JSON.stringify(tokenData), "EX", this.defaultExpiresSeconds);
if (ret != 'OK') {
console.log('set token to redis db fail:' + ret);
}
return tokenData; return tokenData;
} }
} catch (err) {
console.log(err)
}
return null return null;
}; };
// 删除Token记录 // 删除Token记录
AuthToken.prototype.delToken = async function (userToken) { AuthToken.prototype.del = async function (userToken) {
let tokenData = await this.tokenDB.get(userToken).then(function (data) { let tokenData = await this.tokenDB.get(userToken).then(function (data) {
return JSON.parse(data); return JSON.parse(data);
}); });
@ -58,25 +73,25 @@ AuthToken.prototype.delToken = async function (userToken) {
}; };
// 检查Token是否存在 // 检查Token是否存在
AuthToken.prototype.checkToken = async function (userToken, updateExpire = true) { AuthToken.prototype.check = async function (userToken, updateExpire = true) {
let tokenData = await this.tokenDB.get(userToken).then(function (data) { try {
return JSON.parse(data);
});
// token不存在
if (!tokenData) {
return null;
}
if (updateExpire) { if (updateExpire) {
this.tokenDB.expires(userToken, tokenData.ttl) if (await this.tokenDB.expire(userToken, this.defaultExpiresSeconds) >= 1) {
return true;
} }
} else {
return tokenData; if (await this.tokenDB.exists([userToken]) >= 1) {
return true;
}
}
} catch (err) {
console.log(err);
}
return false;
}; };
// 获取Token数据 // 获取Token数据
AuthToken.prototype.getTokenData = async function (userToken) { AuthToken.prototype.get = async function (userToken) {
let tokenData = await this.tokenDB.get(userToken).then(function (data) { let tokenData = await this.tokenDB.get(userToken).then(function (data) {
return JSON.parse(data); return JSON.parse(data);
}); });
@ -89,42 +104,29 @@ AuthToken.prototype.getTokenData = async function (userToken) {
return tokenData; return tokenData;
}; };
AuthToken.prototype.checkTokenKoaRequest = async function (ctx, next) { AuthToken.prototype.koaRequest = async function (ctx, next) {
let token = ctx.request.body.token let token = ctx.request.body.token;
if (!token) token = ctx.header['authorization'] if (!token) token = ctx.header["authorization"];
if (!token) token = ctx.header['token'] if (!token) token = ctx.header["token"];
if (!token) { if (!token) {
ctx.body = { code: 401, msg: 'Need user token.', data: {} }; ctx.body = { code: 401, msg: "Need user token.", data: {} };
return; return;
} }
let tokenData = await this.checkToken(token); let ret = await this.check(token);
if (!tokenData) { if (!ret) {
ctx.body = { code: 401, msg: 'User token not exist.', data: {} }; ctx.body = { code: 401, msg: "User token not exist.", data: {} };
return; 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(); return next();
}; };
/*
AuthToken.prototype.checkTokenKoaRequestByAgent = async function (ctx, next) {
return this.checkTokenKoaRequest(ctx, ctx.userAgent.source, true, next);
};
*/
let tokenInstance = null; let tokenInstance = null;
module.exports = function getTokenInstance(redisdb) { module.exports = function getTokenInstance(redisdb, defaultExpiresSeconds) {
if (!tokenInstance) { if (!tokenInstance) {
tokenInstance = new AuthToken(redisdb); tokenInstance = new AuthToken(redisdb, defaultExpiresSeconds);
} }
return tokenInstance; return tokenInstance;
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "@ehason/auth", "name": "@ehason/auth",
"version": "1.1.1", "version": "1.3.3",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@ehason/auth", "name": "@ehason/auth",
"version": "1.3.3", "version": "1.3.4",
"description": "User auth lib", "description": "User auth lib",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

1735
test/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -20,16 +20,20 @@ app.use(userAgent);
app.use(cors({ origin: "*" })); app.use(cors({ origin: "*" }));
app.use(serve(path.join(__dirname, './public'))); app.use(serve(path.join(__dirname, './public')));
let db = new Redis(6379, '192.168.0.2', { family: 4, db: 0, password: 'sleton' }) let db = new Redis(6379, '39.103.163.220', { family: 4, db: 0, password: 'ehason' })
const Token = require("../auth/index")(db); const Token = require("../auth/index")(db, 60 * 30);
const router = new Router(); const router = new Router();
router.post('/gen', async (ctx, next) => { router.get('/gen', async (ctx, next) => {
let a = await Token.genToken({ name: 'like' }, 'key', 100) let tk = await Token.genToken({ uid: '1111', appid: '222' })
let a = await Token.checkToken(tk)
let d = await Token.getTokenData(tk)
ctx.request.body.token = tk;
Token.checkTokenKoaRequest(ctx, next)
ctx.body = { token: a } ctx.body = { token: a }
}); });
router.post('/check', async (ctx, next) => { router.get('/check', async (ctx, next) => {
Token.checkTokenKoaRequest(ctx, 'key', next) Token.checkTokenKoaRequest(ctx, 'key', next)
}); });