解决:微信公众号开发公司内网代理问题

写在开头

我们项目是使用Vue 和 Node.js的组合,所以文中的所以代码均是Js代码。
本文介绍的是验证服务器,以及获取网页授权的初步过程遇到的代理问题,其他接口大同小异,就不过多介绍了。


验证域名服务器

这是做公众号开发必备的第一部,它要求开发者准备好自己的服务器和域名,并且有一个指定的接口可以返回指定信息:

解决:微信公众号开发公司内网代理问题_第1张图片
下面我来介绍一下这个功能点的实现,其实就是Nginx中配置好路径,比如/my_path跳转到我们的服务上,后台服务中已经实现我我们的 /api/validateAccessToken 接口,具体如下:

const { WECHAT_TOKEN, WECHAT_CONFIG } = require('../config');
const crypto = require('crypto');
const request = require('request');
const { getLog } = require("../utils/log");
const logger = getLog('wechat_service');

/**
     *  参数        描述
     *  signature   微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
     *  timestamp   时间戳
     *  nonce       随机数
     *  echostr     随机字符串
     * @param {*} signature 
     * @param {*} timestamp 
     * @param {*} nonce 
     * @param {*} echostr 
     */
     async createAccessToken(signature, timestamp, nonce, echostr) {
        try {
            //1.将token、timestamp、nonce三个参数进行字典序排序
            let array = [WECHAT_TOKEN, timestamp, nonce];
            array.sort();

            //2.将三个参数字符串拼接成一个字符串进行sha1加密
            let tempStr = array.join('');
            const hashCode = crypto.createHash('sha1');  
            let resultCode = hashCode.update(tempStr, 'utf8').digest('hex'); 
            logger.info(`resultcode is : ${resultCode}`);

            //3.开发者获得加密后的字符串可与signature对比,确认该请求来源于微信
            if (resultCode === signature) {
                logger.info(`createAccessToken resultCode is equql to signature`);
                return echostr;
            } else {
                logger.info(`createAccessToken resultCode is not equql to signature`);
                return 'mismatch';
            }
        } catch (err) {
            logger.error(`createAccessToken error is : ${err && err.message || ''}`);
            return 'mismatch_error';
        }
    }

这里需要注意的是字典序排序,其实在Js里就是Sort一下就行了。如果相等就返回echostr, 不相等就返回mismatch


获取code

配置好服务器之后 ,在测试号上配置好我们自己 的菜单,直接通过链接跳转回调获取 Code,具体参考如下:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

这里的REDIRECT_URI就是直接配置到你的服务器前端路径,这样拿到Code就会直接带到你的项目上去了。
测试号配置菜单可以参考: 微信公众平台接口调试工具-配置菜单


获取Access_token

好了,拿到Code 就可以开发下面的接口了,第一步没有什么问题。但是,在开发下面这个接口的时候,由于公司网络的原因,必须要加代理才能调用,下面不多说,直接上代码:

const { WECHAT_TOKEN, WECHAT_CONFIG } = require('../config');
const crypto = require('crypto');
const request = require('request');
const { getLog } = require("../utils/log");
const logger = getLog('wechat_service');
 	/**
     * 根据Code获取 OpenId和网页授权Access_token, 
     * 这里的Access_token与基础支持中的Access_token不一样
     * @param {*} code 
     */
    async getNetAccessToken(code) {
        try {

            logger.info(`come into getAccessToken Code is : ${code}`);

            return new Promise((resolve, reject) => {
                let pr = request.defaults({ 'proxy': WECHAT_CONFIG.proxy, rejectUnauthorized: false }); 

                pr.get(
                    `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${WECHAT_CONFIG.appid}&secret=${WECHAT_CONFIG.appsecret}&code=${code}&grant_type=authorization_code`,
                    (error, response, body) => {
                        if (response && response.statusCode == 200) {
                            var data = JSON.parse(body);
                            var access_token = data.access_token;
                            var openid = data.openid;
                            logger.info(`access_token ${access_token}, openid ${openid}`);
                            return resolve(access_token);
                        } else {
                            logger.info(`callback error ${error}`);
                            return reject('callback error');
                        }
                    })
            })

        } catch (err) {
            logger.error(`getAccessToken error is : ${err && err.message || ''}`);
            return;
        }
    }

这个方法,就是根据页面上拿到的Code去获取网页授权的Access_tokenOpenid 主要是下面这一句

let pr = request.defaults({ 'proxy': WECHAT_CONFIG.proxy, rejectUnauthorized: false }); 

这里的WECHAT_CONFIG.proxy具体为: http://xx.xx.xx.xx:port

也就是说,必须带上http://否则这个request的包不会识为它是个正确的代理地址。还有一点就是,rejectUnauthorized: false因为微信的Api接口是https的,所以这里还要把证书校验去掉。

至此,接口可以正常调通。
 

 

最后

希望本文可以帮助到那些同样在公司内网开发的同学们。
 

 

 

你可能感兴趣的:(前端,异常,node.js,vue.js,微信公众号,代理)