123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- 'use strict';
- const assert = require('assert');
- const uuid = require('uuid');
- const _ = require('lodash');
- const { BusinessError, ErrorCode } = require('naf-core').Error;
- const crypto = require('crypto');
- const Service = require('egg').Service;
- class WeixinAuthService extends Service {
- constructor(ctx) {
- super(ctx, {});
- }
- // 取得微信AccessToken
- async accesstoken({ appid }) {
- assert(appid, '缺少appid参数项');
- const key = `visit:auth:accesstoken:${appid}`;
- const val = await this.app.redis.get(key);
- const data = {};
- if (val) {
- const { access_token } = JSON.parse(val);
- data.access_token = access_token;
- } else {
- const { wxapi } = this.app.config;
- const appidlist = wxapi;
- const wxapp = _.find(appidlist, { appid });
- const feturl = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${wxapp.appSecret}`;
- const result = await this.ctx.curl(feturl, {
- method: 'get',
- headers: {
- 'content-type': 'application/json',
- },
- dataType: 'json',
- });
- console.log(result);
- if (result) {
- // console.log(result);
- const val = JSON.stringify(result.data);
- await this.app.redis.set(key, val, 'EX', 7200);
- data.access_token = result.data.access_token;
- }
- }
- console.log(`data=>${JSON.stringify(data)}`);
- return data;
- }
- // 取得微信jsapiticket
- async jsapiticket({ appid }) {
- assert(appid, '缺少appid参数项');
- const result = await this.accesstoken({ appid });
- const accesstoken = result.access_token;
- console.log(`accesstoken=>${accesstoken}`);
- assert(accesstoken, '缺少access_token参数项');
- const key = `visit:auth:jsapiticket:${appid}`;
- const val = await this.app.redis.get(key);
- const data = {};
- if (val) {
- const { ticket } = JSON.parse(val);
- data.ticket = ticket;
- } else {
- const feturl = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${accesstoken}&type=jsapi`;
- const result = await this.ctx.curl(feturl, {
- method: 'get',
- headers: {
- 'content-type': 'application/json',
- },
- dataType: 'json',
- });
- if (result) {
- // console.log(result);
- if (result.data.errcode === 0) {
- const val = JSON.stringify(result.data);
- await this.app.redis.set(key, val, 'EX', 7200);
- data.ticket = result.data.ticket;
- }
- }
- }
- return data;
- }
- // 签名算法
- async getsign({ appid, url }) {
- assert(appid, '缺少appid参数项');
- assert(url, '缺少url参数项');
- const result = await this.jsapiticket({ appid });
- // const { wxapi } = this.app.config;
- // const appidlist = wxapi;
- // const wxapp = _.find(appidlist, { appid });
- console.log(`url=>${url}`);
- const noncestr = await this.createNonceStr();
- const timestamp = await this.createTimestamp();
- const ret = {
- jsapi_ticket: result.ticket,
- noncestr,
- timestamp,
- url,
- };
- console.log(ret.data);
- const string = await this.raw(ret);
- ret.sign = await this.sha1(string);
- ret.appid = appid;
- // console.log('ret', ret);
- return ret;
- }
- // sha1加密
- async sha1(str) {
- const shasum = crypto.createHash('sha1');
- shasum.update(str);
- str = shasum.digest('hex');
- return str;
- }
- // 生成签名的时间戳
- async createTimestamp() {
- return parseInt(new Date().getTime() / 1000) + '';
- }
- // 生成签名的随机串
- async createNonceStr() {
- return Math.random().toString(36).substr(2, 15);
- }
- // 对参数对象进行字典排序
- // @param {对象} args 签名所需参数对象
- // @return {字符串} 排序后生成字符串
- async raw(args) {
- let keys = Object.keys(args);
- keys = keys.sort();
- const newArgs = {};
- keys.forEach(function(key) {
- newArgs[key.toLowerCase()] = args[key];
- });
- let string = '';
- for (const k in newArgs) {
- string += '&' + k + '=' + newArgs[k];
- }
- string = string.substr(1);
- return string;
- }
- }
- module.exports = WeixinAuthService;
|