From 480d96828d4fbe507ca33a7ea684c401fe9b7d5a Mon Sep 17 00:00:00 2001 From: suwenxiong Date: Wed, 30 Jan 2019 10:13:43 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96token=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=94=A8=E6=88=B7=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 3 +- .../InterfaceCol/InterfaceColMenu.scss | 1 + server/controllers/base.js | 54 ++++++++++----- server/controllers/project.js | 6 +- server/utils/commons.js | 2 + server/utils/token.js | 67 +++++++++++++++++++ 6 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 server/utils/token.js diff --git a/.eslintrc.js b/.eslintrc.js index b9a3771b..d94b63ea 100755 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -24,7 +24,8 @@ module.exports = { "comma-dangle": ["error", "never"], "no-console": ["off"], "import/no-unresolved": ["off"], - "react/no-find-dom-node": ["off"] + "react/no-find-dom-node": ["off"], + "no-empty": ["off"] // "react/no-unescaped-entities": 0 } }; diff --git a/client/containers/Project/Interface/InterfaceCol/InterfaceColMenu.scss b/client/containers/Project/Interface/InterfaceCol/InterfaceColMenu.scss index 2acef199..7e66f6a8 100755 --- a/client/containers/Project/Interface/InterfaceCol/InterfaceColMenu.scss +++ b/client/containers/Project/Interface/InterfaceCol/InterfaceColMenu.scss @@ -149,6 +149,7 @@ .autoTestsModal { .autoTestUrl { + overflow: auto; background-color: #f5f5f5; border: 1px solid #f1f1f1ce; padding: 16px; diff --git a/server/controllers/base.js b/server/controllers/base.js index f0f0f7e6..58a4d6c5 100755 --- a/server/controllers/base.js +++ b/server/controllers/base.js @@ -6,7 +6,7 @@ const groupModel = require('../models/group.js'); const tokenModel = require('../models/token.js'); const _ = require('underscore'); const jwt = require('jsonwebtoken'); -const OPENAPI_USER = 99999999; +const {parseToken} = require('../utils/token') class baseController { constructor(ctx) { @@ -54,26 +54,51 @@ class baseController { let token = params.token; if (token && openApiRouter.indexOf(ctx.path) > -1) { - if (this.$auth) { - ctx.params.project_id = await this.getProjectIdByToken(token); + let tokens = parseToken(token) - if (!ctx.params.project_id) { - return (this.$tokenAuth = false); - } - return (this.$tokenAuth = true); + const oldTokenUid = '999999' + + let tokenUid = oldTokenUid; + + if(!tokens){ + let checkId = await this.getProjectIdByToken(token); + if(!checkId)return; + }else{ + token = tokens.projectToken; + tokenUid = tokens.uid; } + // if (this.$auth) { + // ctx.params.project_id = await this.getProjectIdByToken(token); + + // if (!ctx.params.project_id) { + // return (this.$tokenAuth = false); + // } + // return (this.$tokenAuth = true); + // } + let checkId = await this.getProjectIdByToken(token); + if(!checkId){ + ctx.body = yapi.commons.resReturn(null, 42014, 'token 无效'); + } let projectData = await this.projectModel.get(checkId); if (projectData) { ctx.params.project_id = checkId; this.$tokenAuth = true; - this.$uid = OPENAPI_USER; - this.$user = { - _id: this.$uid, - role: 'member', - username: 'system' - }; + this.$uid = tokenUid; + let result; + if(tokenUid === oldTokenUid){ + result = { + _id: tokenUid, + role: 'member', + username: 'system' + } + }else{ + let userInst = yapi.getInst(userModel); //创建user实体 + result = await userInst.findById(tokenUid); + } + + this.$user = result; this.$auth = true; } } @@ -263,9 +288,6 @@ class baseController { */ async checkAuth(id, type, action) { let role = await this.getProjectRole(id, type); - if(this.getUid() === OPENAPI_USER){ - role = 'dev' - } if (action === 'danger') { if (role === 'admin' || role === 'owner') { diff --git a/server/controllers/project.js b/server/controllers/project.js index 44e0e865..be132919 100755 --- a/server/controllers/project.js +++ b/server/controllers/project.js @@ -13,7 +13,7 @@ const logModel = require('../models/log.js'); const followModel = require('../models/follow.js'); const tokenModel = require('../models/token.js'); const url = require('url'); - +const {getToken} = require('../utils/token') const sha = require('sha.js'); class projectController extends baseController { @@ -1004,11 +1004,14 @@ class projectController extends baseController { .update(passsalt) .digest('hex') .substr(0, 20); + await this.tokenModel.save({ project_id, token }); } else { token = data.token; } + token = getToken(token, this.getUid()) + ctx.body = yapi.commons.resReturn(token); } catch (err) { ctx.body = yapi.commons.resReturn(null, 402, err.message); @@ -1037,6 +1040,7 @@ class projectController extends baseController { .digest('hex') .substr(0, 20); result = await this.tokenModel.up(project_id, token); + token = getToken(token); result.token = token; } else { ctx.body = yapi.commons.resReturn(null, 402, '没有查到token信息'); diff --git a/server/utils/commons.js b/server/utils/commons.js index 22f46976..acdf91ef 100755 --- a/server/utils/commons.js +++ b/server/utils/commons.js @@ -14,6 +14,8 @@ const _ = require('underscore'); const Ajv = require('ajv'); const Mock = require('mockjs'); + + const ejs = require('easy-json-schema'); const jsf = require('json-schema-faker'); diff --git a/server/utils/token.js b/server/utils/token.js new file mode 100644 index 00000000..0557f590 --- /dev/null +++ b/server/utils/token.js @@ -0,0 +1,67 @@ +const yapi = require('../yapi') + +const crypto = require('crypto'); + +/* + 下面是使用加密算法 +*/ + +// 创建加密算法 +const aseEncode = function(data, password) { + + // 如下方法使用指定的算法与密码来创建cipher对象 + const cipher = crypto.createCipher('aes192', password); + + // 使用该对象的update方法来指定需要被加密的数据 + let crypted = cipher.update(data, 'utf-8', 'hex'); + + crypted += cipher.final('hex'); + + return crypted; +}; + +// 创建解密算法 +const aseDecode = function(data, password) { + /* + 该方法使用指定的算法与密码来创建 decipher对象, 第一个算法必须与加密数据时所使用的算法保持一致; + 第二个参数用于指定解密时所使用的密码,其参数值为一个二进制格式的字符串或一个Buffer对象,该密码同样必须与加密该数据时所使用的密码保持一致 + */ + const decipher = crypto.createDecipher('aes192', password); + + /* + 第一个参数为一个Buffer对象或一个字符串,用于指定需要被解密的数据 + 第二个参数用于指定被解密数据所使用的编码格式,可指定的参数值为 'hex', 'binary', 'base64'等, + 第三个参数用于指定输出解密数据时使用的编码格式,可选参数值为 'utf-8', 'ascii' 或 'binary'; + */ + let decrypted = decipher.update(data, 'hex', 'utf-8'); + + decrypted += decipher.final('utf-8'); + return decrypted; +}; + +const defaultSalt = 'abcde'; + +exports.getToken = function getToken(token, uid){ + if(!token)throw new Error('token 不能为空') + yapi.WEBCONFIG.passsalt = yapi.WEBCONFIG.passsalt || defaultSalt; + return aseEncode(uid + '|' + token, yapi.WEBCONFIG.passsalt) +} + +exports.parseToken = function parseToken(token){ + if(!token)throw new Error('token 不能为空') + yapi.WEBCONFIG.passsalt = yapi.WEBCONFIG.passsalt || defaultSalt; + let tokens; + try{ + tokens = aseDecode(token, yapi.WEBCONFIG.passsalt) + }catch(e){} + if(tokens && typeof tokens === 'string' && tokens.indexOf('|') > 0){ + tokens = tokens.split('|') + return { + uid: tokens[0], + projectToken: tokens[1] + } + } + return false; + +} +