123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- 'use strict';
- const Controller = require('egg').Controller;
- const jsonwebtoken = require('jsonwebtoken');
- const FormStream = require('formstream');
- 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;
- // 参数定义
- let form = {};
- const options = {
- method: requestMethod,
- data,
- nestedQuerystring: true,
- };
- // 如果是文件上传
- if (method === 'upload') {
- const stream = await this.ctx.getFileStream();
- form = new FormStream();
- form.stream(stream.fieldname, stream, stream.filename);
- options.stream = form;
- options.headers = form.headers();
- }
- // 发送请求
- const res = await this.ctx.curl(`${address}${path}`, options);
- // 默认返回值
- msg = res.data;
- // 日志详情默认值
- details = data;
- result = '成功';
- // 错误异常处理(返回值)
- // 异常抛出检测
- if (res.status === 500) {
- msg = { errcode: -1002, errmsg: '系统错误', details: '未知错误类型' };
- details = {};
- 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);
- // 没有匹配数据 默认放过 不验证jwt放过
- if (!item || !item.jwt) return { errcode: 0, details: '' };
- // 获取token
- const token = this.ctx.header.authorization;
- 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: decode._doc };
- } 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;
|