记一次公众号菜单配置

要求是这样的,公众号配置菜单,用户点击菜单时要将该用户的 openid 和 unionid 追加到菜单地址后面。

太简单了

对于我这个没有搞过公众号的后端开发来说,这还不简单吗,
菜单配置的是我的后端地址,点击菜单请求到后端,后端获取到该用户的信息,将 openid 和 unionid 拼接到请求菜单 url 上,然后重定向到真正的菜单地址,搞定,很简单。

但是我知道没有这么简单。

本着严谨的态度,我把微信公众号官方文档看了一遍,主要是配置菜单的部分,直到我看到自定义菜单有 CLICK 类型,用户点击时微信后台会推送事件到我的后端,

click:点击推事件用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互

看到这,我觉得事情更简单了,我配置一个 CLICK 类型的菜单不就行了,微信后台发送事件到我的后端,然后我给他重定向,不是更简单了。

够用,剩下的文档咱不看了。

真就太简单了

要么说咱没搞过呢,无所畏惧,事情想的太简单了。

我先尝试了 click 类型的菜单,发现微信后台推送过来的真就只是一个事件,我接收到了,然而只能对这个事件回复消息,并不能进行重定向,跳转到其他页面。

随后我尝试了我最初的想法,菜单配置我的后端地址,后端进行重定向。

菜单配置了,点击也能到我的后端,这时候问题来了,我拿什么获取到用户信息。

没有。什么都没有。
我的脑海里突然一片空白,就像电视机突然失去信号,只剩下一片静谧的雪花点。
我愣住了,像一座石像,僵硬而无法移动,眼神空洞地凝视着前方屏幕。
中午了,先吃饭吧。

我是后端,要什么前端

一上午的时间过去了,事情没有得到一点进展。
在程序员微信群里我询问了一下,这个场景应该怎么解决,热心网友告诉我 需要网页授权信息。
接着看文档,这次主要是网页授权这部分。

第一步:用户同意授权,获取code

第二步:通过code换取网页授权access_token

第三步:刷新access_token(如果需要)

第四步:拉取用户信息(需scope为 snsapi_userinfo)

网页授权就是这4个步骤,看起来只需要后端就行了,前端不需要。

文档后面有这么一句

用户同意授权后

如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。

根据这篇文档,调整自己的技术方案,
微信公众号的菜单配置的是用户授权,redirect_uri 配置的是我的后端地址,页面跳转到我后端的时候我就能拿到 code,就能获取到用户信息然后重定向。

前端还是需要的

当我写好了后端,配置好菜单后,微信后台确实将请求回调到了我的后端,但是 code=code,你没有看错,我接收到的 code 参数的值就是 code。

我的思绪如同被打乱的棋局,我试图找到那个决定性的步骤,但我无法理解。

后来,在网上看到一篇文章,说在页面上 alert(window.location.href) 你会发现,地址里是有 code 的。

我知道,决定性的那个步骤我找到了。就是前端页面。但我无法理解。

于是,我写了一个 html 页面,就执行 alert 这行代码,我到底要看看到底能不能获取到 code。
果然,页面上的 code 他真有值。

这时,最终的技术方案形成了。
微信公众号的菜单配置的是用户授权地址,redirect_uri 这个参数是我的页面地址,在我的页面中获取到 code,然后带着 code 请求我的后端,后端拿到 code 获取到用户信息,然后拼接到一个链接上进行重定向操作。

最终我也是在这个方案的基础上实现的。

这个页面需要注意的

  1. 不要有 title,不然微信菜单点击之后会有一个页面 title 出现
  2. 直接用 window.location.href 去请求后端地址,让后端去重定向。这样前端没有访问历史记录。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script>
        console.log(window.location.href);
        window.onload = function () {
            let params = new URLSearchParams(window.location.search);
            let code = params.get('code');
            let state = params.get('state');
            let redirectCode = params.get('redirectCode');
            console.log("code = ", code);
            console.log("redirectCode = ", redirectCode);

            let baseDomain = "http://localhost:8080";
            let fetchUrl = baseDomain + "/wx/redirect?code=" + code + "&state=" + state + "&redirectCode=" + redirectCode;
            console.log(fetchUrl)
            window.location.href=fetchUrl
        }
    </script>
</head>
<body>
</body>
</html>

没有一个字是多余的

微信网页授权,真就没有一个字是多余的。


欢迎关注微信公众号

2024/01/10 09:51 上午