微信公众号开发入门,配置与获取AccessToken

专栏收录该内容

Hi I'm Shendi



最近做微信公众号开发,在这里记录下来

在语言方面,我选择的 node.js,因为占内存低,而且开发效率快,之前一直都是用Java,但一个SpringBoot就吃一百多M属实吃不消...



配置

在公众号的设置与开发 -> 基本配置 -> 服务器配置

配置


点击修改配置,有三个参数一个选项

服务器地址(URL)填接口地址,这个接口地址要处理两个请求类型

GET,在修改配置确认的时候用来验证,验证过了才修改成功,

POST,可以查看微信公众号文档的基础消息能力部分:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html。当用户关注、取消关注、发消息等,微信服务器会把数据发到这个接口


令牌(Token),这个自己随便输入就可以了,是上面说到的修改配置验证GET请求那个时候要使用到的

消息加解密密钥(EncodingAESKey),最后一项选的是明文就不需要管这个了,不是明文可以自己输入或者点击右边的一键生成,上面说到的POST请求,微信服务器发数据给接口的时候,会将数据加密,AES加密,密钥是这个

消息加解密方式,根据需求选择,但一般都选安全模式吧


上面这些操作完后,还不能点击确定按钮,点击确定按钮微信服务器就会发上面说的GET请求请求给我们填写的服务器地址,于是我们先要编写处理接口


接口细节内容如下

若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。

​ 1)将token、timestamp、nonce三个参数进行字典序排序

​ 2)将三个参数字符串拼接成一个字符串进行sha1加密

​ 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信


我使用的nodejs,用的Express框架,将 get 和 post 合在一起了,只需要看 req.method == 'GET' 部分的代码就可以了,代码如下

router.all('/路由地址', (req, res, next) => {
    let method = req.method;
    if (method != 'GET' && method != 'POST') {
        res.send();
        return;
    }
    
    var signature = req.query.signature,
        timestamp = req.query.timestamp,
        nonce = req.query.nonce,
        echostr = req.query.echostr;

    if (req.method == 'GET') {
        if (signature != null && timestamp != null && nonce != null && echostr != null) {
            var data = [timestamp, nonce, "这里是填写的token"].sort().join("");
    
            var sha1 = crypto.createHash("sha1");
            if (signature == sha1.update(data).digest("hex")) {
                res.send(echostr);
                return;
            }
        }
        
        res.statusCode = 404;
        res.send();
    } else {
        console.log(req.read().toString());
        res.send("");
    }
});

如果你也是使用的 node.js,上面代码涉及到了Express和sha1加密

关于 Express 可以查阅这篇文章:https://sdpro.top/blog/html/article/1087.html

关于 sha1 加密可以查阅这篇文章:https://sdpro.top/blog/html/article/1088.html



申请测试号

如果你已经有公众号,刚创建不久没有正式运营的话,那可以忽略此步骤

如果你的公众号已经配置好了自定义菜单,自动回复,被关注回复...等,那么建议申请个测试号来进行开发调试

因为上面配置的启用,会自动停用自定义菜单,自动回复等


申请测试号还是挺简单的,进入以下链接点登录,然后用微信扫个码就可以了

https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

然后就进入了测试号页面了

测试号


里面的接口配置信息和上面说的配置是一样的,但是只有URL和Token,没有加密方面的,因为是测试嘛,官方认为明文比较好调试吧



获取AccessToken

官方文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html

accesstoken用来得到一串令牌,在调用其他接口的时候会需要用到,所以这部分是开发的第一步

需要 appid 和 secret,这些在公众号平台可以找到,测试号的话页面上直接就有了

测试号的话需要注意一下,secret有可能会变(具体也不知道是啥原因),有可能只是个例吧,刷新页面更改新secret就好了

http请求,get类型,带着参数调用以下地址就可以获取到AccessToken了

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=secret

参数 是否必须 说明
grant_type 获取access_token填写client_credential
appid 第三方用户唯一凭证
secret 第三方用户唯一凭证密钥,即appsecret

正常情况下响应以下内容

{"access_token":"ACCESS_TOKEN","expires_in":7200}

而 access_token 就是令牌了,expires_in是有效时间,单位秒

当令牌过期后就需要重新申请令牌了

于是我的代码如下

var appId = "公众号的appid",
    appSecret = "公众号的secret";

var accessToken = {
    val : "",
    // 创建时间,秒
    time : null,
    // 多久后过期,秒
    timeout : null,
};
function getAccessToken(appid, secret) {
    if (!appid) appid = appId;
    if (!secret) secret = appSecret;

    return new Promise((resolve, reject) => {
        // 提前十秒过期,未过期则继续用
        if (accessToken.time != null && accessToken.timeout != null && (parseInt(new Date().getTime() / 1000)) - accessToken.time <= timeout - 10) {
            resolve(accessToken.val);
        } else {
            axios({
                url: `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`,
                method: 'get'
            }).then((res) => {
                accessToken.val = res.data.access_token;
                accessToken.time = parseInt(new Date().getTime() / 1000);
                accessToken.timeout = res.data.expires_in;

                resolve(accessToken.val);
            }).catch((res) => {
                console.log(`请求出错:${res}`);
                reject(res);
            });
        }
    });
}

使用方法如下

getAccessToken().then((accessToken) => {
    // accessToken就是令牌了
});

上面的部分使用到了 axios,关于axios可以查阅这篇文章:https://sdpro.top/blog/html/article/1094.html




END

本文链接:https://sdpro.top/blog/html/article/1096.html

♥ 赞助 ♥

尽管去做,或许最终的结果不尽人意,但你不付出,他不付出,那怎会进步呢?