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}×tamp=${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 插件