cool 框架 node 后端封装三方Api post请求函数

1.需求

现在一些数据源 ,需要从三方地址拿到一些数据 比如说电影列表 信息了 影院列表信息了 等一些展示的数据,但是人家这种东西 害需要使用 appkey appserect 这种验签

这种需求 你前端调用接口是直接调用不了的 因为需要用到验签 需要后端接口转接一下 前端再去调用接口

复制代码
import { Body, Config, Provide } from '@midwayjs/decorator';
import { Inject } from '@midwayjs/decorator';
import { BusinessStudentEntity } from '../entity/student';
import { BusinessUserEntity } from '../entity/user';
import { BusinessBaseConfigEntity } from '../entity/base/config';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';

import { BaseService } from '@cool-midway/core';
import * as request from 'request';
import * as _ from 'lodash';
import * as crypto from 'crypto';
import { Context } from '@midwayjs/koa';

/**
 * http请求封装
 */
@Provide()
export class BussinessRequestService extends BaseService {
  @Inject()
  ctx: Context;

  @InjectEntityModel(BusinessStudentEntity)
  businessStudentEntity: Repository<BusinessStudentEntity>;

  @InjectEntityModel(BusinessBaseConfigEntity)
  businessBaseConfigEntity: Repository<BusinessBaseConfigEntity>;

  @InjectEntityModel(BusinessUserEntity)
  businessUserEntity: Repository<BusinessUserEntity>;

  @Config('module.business')
  coolConfig;

  /**
   * post
   */
  async post(url, data = {}) {
    const { userId } = this.ctx.clientInfo;
    //学员信息
    const studentInfo = await this.businessStudentEntity.findOneBy({
      id: userId,
    });
    //对应 导员信息
    const adminInfo = await this.businessBaseConfigEntity.findOneBy({
      userId: String(studentInfo?.userId),
    });
    const requestConfig = this.coolConfig.request;
    let time = new Date().getTime();
    let pararm = {};
    pararm['appId'] = adminInfo.liangPiaoAppId;
    pararm['timestamp'] = time;
    let sign = this.generateSignature(
      pararm,
      data,
      adminInfo.liangPiaoSecret,
      adminInfo.liangPiaoAppId
    );
    return new Promise((resolve, reject) => {
      var option = {
        url:
          requestConfig.base_url +
          url +
          `?appId=${adminInfo.liangPiaoAppId}&sign=${sign}&timestamp=${time}`,
        method: 'POST',
        json: true,
        timeout: 30000,
        headers: {
          'content-type': 'application/json',
        },
        body: data,
      };
      request(option, function (error, response, body) {
        if (!error && response.statusCode == 200) {
          const { state, data } = body;
          if (state === 200) {
            resolve(data);
          } else {
            reject(body);
          }
        } else {
          reject(error); // 返回错误信息
        }
      });
    });
  }
  /**
   * get
   */
  // get(url, params = {}) {
  //   const requestConfig = this.mangoConfig.request;
  //   params['appId'] = requestConfig.appKey;
  //   params['timestamp'] = new Date().getTime();
  //   params['sign'] = this.generateSignature(
  //     params,
  //     requestConfig.appSecret,
  //     requestConfig.appKey,
  //     params['timestamp']
  //   );

  //   return new Promise((resolve, reject) => {
  //     var option = {
  //       url: requestConfig.base_url + url,
  //       method: 'GET',
  //       timeout: 30000,
  //       qs: params,
  //     };
  //     request(option, function (error, response, body) {
  //       if (!error && response.statusCode == 200) {
  //         const { code, data } = body;
  //         if (code === 1) {
  //           resolve(data);
  //         } else {
  //           reject(body);
  //         }
  //       } else {
  //         reject(error); // 返回错误信息
  //       }
  //     });
  //   });
  // }

  //计算签名
  generateSignature(params, body, secretKey, keys) {
    const joinedParams = this.joinRequestParams(params, body, secretKey, keys);
    const md5Hash = crypto
      .createHash('md5')
      .update(joinedParams)
      .digest('hex')
      .toUpperCase();

    return md5Hash;
  }
  //计算签名
  joinRequestParams(params, body, secretKey, keys) {
    const sb = [secretKey]; // 前面加上 secretKey
    const sortedParams = Object.keys(params)
      .filter(key => key !== 'sign' && params[key]) // 过滤掉不需要的键
      .sort(); // 对键进行排序

    for (const key of sortedParams) {
      sb.push(key + params[key]);
    }
    sb.push(JSON.stringify(body));
    sb.push(secretKey); // 最后加上 secretKey

    return sb.join('');
  }
}

当然一般 这种三方API 都有人家规定的验签规则 让你 写什么样的格式 拼接成什么样的格式

得看实际的需求 我这里主要介绍的是 post 请求的封装 (在jsNode 中书写后端接口) 是需要引入request 插件

相关推荐
星恒随风1 小时前
C++11详解(一):统一初始化——列表初始化与 initializer_list
c++·笔记·学习·list·状态模式
木公子1 小时前
Vue3源码精读04:Scheduler 调度器深度解析|异步批量更新与任务队列源码全解
前端·vue.js
软件黑马王子1 小时前
5.单例模式问题3:多线程问题
单例模式·前端框架·c#
开开心心就好1 小时前
手机悬屏翻译工具外语游戏漫画APP全覆盖
android·前端·javascript·python·游戏·pdf·html
李游Leo2 小时前
Node.js 开发环境安装与 npm/pnpm 国内镜像配置(Windows / macOS / Linux)
npm·node.js·pnpm·前端开发·开发环境
光影少年2 小时前
react navite封装一个RN 通用按钮组件
前端·javascript·react native·react.js·前端框架
软件黑马王子2 小时前
1.non-MonoBehaviour 单例模式泛型基类
unity·前端框架·c#
独立开发之道2 小时前
【three.js教程】Three.js 矩阵变换:position/quaternion/scale 和 matrix 到底怎么配合
开发语言·javascript·矩阵
nicole bai2 小时前
dialog封装
前端·javascript·vue.js
小江的记录本3 小时前
【CSS】CSS 核心:盒模型、BFC/IFC、Flex/Grid 布局、响应式布局、移动端适配(附《思维导图》)
前端·css·面试·前端框架·tensorflow·html5·xss