ssr-api.js 2.87 KB
const serviceApi = global.yoho.ServiceAPI;
const ufoAPI = global.yoho.UfoAPI;
const logger = global.yoho.logger;
const _ = require('lodash');
const md5 = require('yoho-md5');
const checkParams = require('../../utils/check-params');
const apiMaps = require('../../config/api-map');

function checkSign(params, sign) {
  delete params.s;
  const sortKeys = Object.keys(params).sort();
  const str = sortKeys.map(key => {
    return `${key}:${encodeURIComponent(params[key])}`;
  }).join('_');

  const signDiff = md5(`${str}_${str.length}`);

  if (sign === signDiff) {
    return true;
  }
  logger.error(`验签不匹配: 提交sign: ${sign}, 服务端sign: ${signDiff}, params: ${JSON.stringify(params)}`);
  return false;
}

module.exports = async(req, res, next) => {
  const apiInfo = apiMaps[req.path];

  if (!apiInfo) {
    return next();
  }
  let baseParams;
  let reqParams = Object.assign({}, req.query, req.body);

  res.set({
    'Cache-Control': 'no-cache',
    Pragma: 'no-cache',
    Expires: (new Date(1900, 0, 1, 0, 0, 0, 0)).toUTCString()
  });

  if (apiInfo.checkSign) {
    if (!checkSign(Object.assign({}, reqParams), reqParams.s)) {
      logger.error(`验签失败!uid: ${_.get(req, 'user.uid', '').toString()}, params: ${JSON.stringify(reqParams)}, ip: ${req.yoho.clientIp}`);
      return res.json({
        code: 400,
        message: '验签失败'
      });
    }
  }

  delete reqParams.s;
  delete reqParams.ts;

  if (!apiInfo.service) {
    baseParams = {
      uid: (req.user && req.user.uid) ? {
        toString: () => {
          return req.user.uid || 0;
        },
        sessionKey: req.user.sessionKey,
        appSessionType: req.user.appSessionType
      } : 1,
      method: apiInfo.api
    };
  }

  try {
    const mergeParams = Object.assign(reqParams, baseParams);
    const params = checkParams.getParams(mergeParams, apiInfo);
    const cache = req.method.toLowerCase() !== 'get' ? false : apiInfo.cache;
    let method = req.method.toLowerCase() === 'post' ? 'post' : 'get';

    let result;

    let apiCtx = req.ctx(global.yoho.BaseModel);

    if (apiInfo.service) {
      result = await apiCtx.get({
        api: serviceApi,
        url: apiInfo.api,
        data: params,
        param: {
          cache: cache,
        }
      });
    } else if (apiInfo.ufo) {
      result = await apiCtx[method]({
        api: ufoAPI,
        url: apiInfo.path || '',
        data: params,
        param: {
          cache: cache
        }
      });
    } else {
      result = await apiCtx[method]({
        data: params,
        url: apiInfo.path || '',
        param: {
          cache: cache
        }
      });
    }
    if (result) {
      return res.json(result);
    }
    return res.json({
      code: 400
    });
  } catch (error) {
    logger.error(error);
    return res.json({
      code: error.code || 500,
      message: error.message || '服务器错误'
    });
  }
};