diff --git a/.gitignore b/.gitignore index c674098..0f4fff3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ # .nfs files are created when an open file is removed but is still being accessed .nfs* +/auth/node_modules/ +/auth/.idea/ diff --git a/auth/.npmrc b/auth/.npmrc new file mode 100644 index 0000000..2c63c08 --- /dev/null +++ b/auth/.npmrc @@ -0,0 +1,2 @@ +{ +} diff --git a/auth/index.js b/auth/index.js new file mode 100644 index 0000000..26a96d3 --- /dev/null +++ b/auth/index.js @@ -0,0 +1,112 @@ +'use strict'; + +const crypto = require('crypto'); +const Redis = require('ioredis'); + +function AuthToken(redisOpt) { + if (!(this instanceof AuthToken)) { + return new AuthToken(redisOpt); + } + + if (!redisOpt) { + throw 'AuthToken: need redis config.'; + } + + this.tokenDB = new Redis(redisOpt); + this.tokenDB.on("connect",function(){ + console.log("AuthToken: ioredis connected: " + JSON.stringify(redisOpt)); + }); +} + +AuthToken.prototype.genToken = async function(userData, expiresSeconds) { + // 生成系统内部的user token + let hash = crypto.createHash('md5'); + hash.update(JSON.stringify(userData)); + let userToken = hash.digest('hex'); + + // 缓存到redis + let tokenData = { + userData: userData, + expires: {ttl: expiresSeconds, ts: Math.floor(Date.now() / 1000)} + }; + 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; +}; + +module.exports = AuthToken; diff --git a/auth/package-lock.json b/auth/package-lock.json new file mode 100644 index 0000000..6289af4 --- /dev/null +++ b/auth/package-lock.json @@ -0,0 +1,80 @@ +{ + "name": "@ehason/auth", + "version": "1.1.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "cluster-key-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", + "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "denque": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", + "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" + }, + "ioredis": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.14.0.tgz", + "integrity": "sha512-vGzyW9QTdGMjaAPUhMj48Z31mIO5qJLzkbsE5dg+orNi7L5Ph035htmkBZNDTDdDk7kp7e9UJUr+alhRuaWp8g==", + "requires": { + "cluster-key-slot": "^1.1.0", + "debug": "^4.1.1", + "denque": "^1.1.0", + "lodash.defaults": "^4.2.0", + "lodash.flatten": "^4.4.0", + "redis-commands": "1.5.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.0.1" + } + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "redis-commands": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.5.0.tgz", + "integrity": "sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg==" + }, + "redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=" + }, + "redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", + "requires": { + "redis-errors": "^1.0.0" + } + }, + "standard-as-callback": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.0.1.tgz", + "integrity": "sha512-NQOxSeB8gOI5WjSaxjBgog2QFw55FV8TkS6Y07BiB3VJ8xNTvUYm0wl0s8ObgQ5NhdpnNfigMIKjgPESzgr4tg==" + } + } +} diff --git a/auth/package.json b/auth/package.json new file mode 100644 index 0000000..7fc7026 --- /dev/null +++ b/auth/package.json @@ -0,0 +1,14 @@ +{ + "name": "@ehason/auth", + "version": "1.1.1", + "description": "User auth lib", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "likeagle", + "license": "MIT", + "dependencies": { + "ioredis": "^4.14.0" + } +} diff --git a/auth/readme b/auth/readme new file mode 100644 index 0000000..149e9c0 --- /dev/null +++ b/auth/readme @@ -0,0 +1 @@ +This is auth token lib for ehason. diff --git a/utils/index.js b/utils/index.js new file mode 100644 index 0000000..e682132 --- /dev/null +++ b/utils/index.js @@ -0,0 +1,6 @@ +exports.yo = function() { + alert('Yo Coder!') +} +exports.hello = function() { + alert('Hello Coder!') +} diff --git a/utils/package.json b/utils/package.json new file mode 100644 index 0000000..a26d1fe --- /dev/null +++ b/utils/package.json @@ -0,0 +1,11 @@ +{ + "name": "@ehason/utils", + "version": "1.0.0", + "description": "Utils for ehason develope", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "likeagle ", + "license": "MIT" +}