|
@@ -0,0 +1,142 @@
|
|
|
+'use strict';
|
|
|
+
|
|
|
+const Controller = require('egg').Controller;
|
|
|
+const jsonwebtoken = require('jsonwebtoken');
|
|
|
+class HomeController extends Controller {
|
|
|
+ async index() {
|
|
|
+ const { modules } = this.app.config;
|
|
|
+ // 路径参数
|
|
|
+ const { agent, service, module, method, item } = this.ctx.params;
|
|
|
+ // 请求地址
|
|
|
+ const address = modules[service];
|
|
|
+ // 请求方法
|
|
|
+ const requestMethod = this.ctx.request.method;
|
|
|
+ // 请求路径
|
|
|
+ const path = this.ctx.path;
|
|
|
+ let msg = null;
|
|
|
+ let details = null;
|
|
|
+ let result = null;
|
|
|
+ // jwt 验证
|
|
|
+ const auth = await this.auth({ service, path });
|
|
|
+ // 验证失败
|
|
|
+ if (auth.errcode !== 0) {
|
|
|
+ this.ctx.status = 401;
|
|
|
+ this.ctx.body = { errcode: 401, errmsg: '身份验证失败', details: auth.details };
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 发送的数据
|
|
|
+ let data = requestMethod === 'GET' ? this.ctx.query : this.ctx.request.body;
|
|
|
+ if (requestMethod === 'DELETE') data = this.ctx.params.item;
|
|
|
+ // 发送请求
|
|
|
+ const res = await this.ctx.curl(`${address}${path}`, {
|
|
|
+ method: requestMethod,
|
|
|
+ data,
|
|
|
+ nestedQuerystring: true,
|
|
|
+ });
|
|
|
+ // 默认返回值
|
|
|
+ msg = res.data;
|
|
|
+
|
|
|
+ // 日志详情默认值
|
|
|
+ details = data;
|
|
|
+ result = '成功';
|
|
|
+
|
|
|
+ // 错误异常处理(返回值)
|
|
|
+ // 缺少字段检测返回asser
|
|
|
+ if (res.status === 500 && res.data.name === 'AssertionError') {
|
|
|
+ msg = { errcode: -1002, errmsg: res.data.message, data: '' };
|
|
|
+ details = res.data.message;
|
|
|
+ result = '失败';
|
|
|
+ }
|
|
|
+ // 异常抛出检测
|
|
|
+ if (res.status === 500 && (res.data.name === 'ValidationError' || res.data.name === 'CastError')) {
|
|
|
+ msg = { errcode: -1002, errmsg: '系统错误', details: res.data.message };
|
|
|
+ details = res.data.message;
|
|
|
+ result = '失败';
|
|
|
+ }
|
|
|
+ await this.setLog({ agent, service, module, method, item, details: JSON.stringify(details), result, auth });
|
|
|
+ // 默认返回状态 = 当前请求返回状态
|
|
|
+ this.ctx.response.type = res.headers['content-type'];
|
|
|
+ this.ctx.status = res.status;
|
|
|
+ this.ctx.body = msg;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 日志记录
|
|
|
+ async setLog({ agent, service, module, method, item, details, result, auth }) {
|
|
|
+ // 配置
|
|
|
+ const { modules, apipath } = this.app.config;
|
|
|
+ // 请求路径
|
|
|
+ const path = this.ctx.path;
|
|
|
+ // 根据service类型 获取配置文件
|
|
|
+ const logmodules = apipath[service];
|
|
|
+ // 没有配置文件默认放过
|
|
|
+ if (logmodules) {
|
|
|
+ // const items = logmodules.find(e => e.url.includes(path));
|
|
|
+ const items = await this.rewrite_path(logmodules, path);
|
|
|
+ if (items && items.log) {
|
|
|
+ // 此处开始记录日志
|
|
|
+ let userName = null;
|
|
|
+ let name = null;
|
|
|
+ if (auth.decode) {
|
|
|
+ userName = auth.decode.userName;
|
|
|
+ name = auth.decode.name;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ await this.ctx.curl(`${modules.log}/api/log/log/create`, {
|
|
|
+ method: 'POST',
|
|
|
+ dataType: 'json',
|
|
|
+ data: { agent, service, module, method, item, details, result, userName, name },
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ this.ctx.logger.error(`日志添加失败: ${error}`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证函数
|
|
|
+ async auth({ service, path }) {
|
|
|
+ const { jwt, apipath } = this.app.config;
|
|
|
+ // 根据service类型 获取配置文件
|
|
|
+ const modules = apipath[service];
|
|
|
+ // 没有配置文件默认放过
|
|
|
+ if (!modules) return { errcode: 0, details: '' };
|
|
|
+ // 获取与当前路径匹配的项
|
|
|
+ // const item = modules.filter(e => e.url.includes(path));
|
|
|
+ const item = await this.rewrite_path(modules, path);
|
|
|
+ // 没有匹配数据 默认放过
|
|
|
+ if (item) return { errcode: 0, details: '' };
|
|
|
+ // 不验证jwt放过
|
|
|
+ if (!item.jwt) return { errcode: 0, details: '' };
|
|
|
+ // 获取token
|
|
|
+ const token = this.ctx.header.authorization.split('Bearer ')[1];
|
|
|
+ try {
|
|
|
+ // 解密jwt
|
|
|
+ const decode = jsonwebtoken.verify(token, jwt.secret);
|
|
|
+ // 如果有验证签发者
|
|
|
+ if (item && item.issuer) {
|
|
|
+ // 比对签发者
|
|
|
+ if (!item.issuer.includes(decode.iss)) return { errcode: -4001, details: 'issuer fail verification' };
|
|
|
+ }
|
|
|
+ return { errcode: 0, details: '', decode };
|
|
|
+ } catch (error) {
|
|
|
+ return { errcode: -4001, details: error.message };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 重写路径
|
|
|
+ async rewrite_path(modules, path) {
|
|
|
+ return modules.find(e => {
|
|
|
+ const { url } = e;
|
|
|
+ let data = null;
|
|
|
+ const urlList = url.split('/');
|
|
|
+ const pathIist = path.split('/');
|
|
|
+ const urlItem = urlList.findIndex(j => j.includes(':'));
|
|
|
+ if (urlItem > 0) data = pathIist[urlItem];
|
|
|
+ if (data !== null) urlList[urlItem] = data;
|
|
|
+ const pathItem = urlList.join('/');
|
|
|
+ if (pathItem === path) return e;
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+module.exports = HomeController;
|