在生产开发过程中,经常接到 “开发挂载在微信公众号上的网页” 的需求。但是需求方往往无法分清"订阅号"、"服务号"的区别,就会导致 “在网页内获取用户信息” 这项子需求无法实现。
微信开发文档内明确说明,订阅号无法直接在网页内获取用户基本信息。

但是真的无法实现吗?实际上,开发者可以通过一些其他的手段变相的实现这类需求。

如何实现

需要了解的关键词

  1. openID: 为了识别用户,每个用户针对每个公众号会产生一个安全的OpenID
  2. 服务器: 微信开发者绑定的服务器地址

实现思路

由于订阅号没有在网页内获取用户信息的权限,因此我们不能将这一步放在网页中。
通过查询微信的开发文档和接口权限文档可以得知,认证过的订阅号可以通过用户的openID获取到用户信息。

而对于每一个微信公众号来说,用户的openID会在用户与公众号产生消息交互后由微信推送给服务器。
在网页端,后台可以将提前获取到的用户信息进行注入。
因此,可以将这几步进行串联,得到的简易流程如下:

对于公众号来说,和用户产生消息消息的方式有很多,比如用户给公众号发送消息,用户点击公众号的tab,用户关注/取消关注…比较符合需求描述的交互场景应该是点击公众号的自定义菜单。

用户点击tab后,微信会将openID推送到服务器,此时服务器可以通过之前提到的微信api获取到用户信息并存入数据库,并生成唯一标志符与用户id一一对应。然后将附带唯一标识符的网页链接返回给用户,让用户点击访问。
在网页内,通过ajax请求直接和服务器交互,获取到预先存入数据库中的用户信息。
更加详细的流程如下:

缺点

这种方式实际上不是正道,最正统的方法还是需要将网页挂载于服务号并使用微信官方的接口。
使用这种方式获取到的用户信息有几个问题:

1. 保持登录态的问题

使用这种方式获取到了用户信息,实际上相当于用户“登录”了所挂载网页,开发者应该将用户登录态写入cookie。那么对于用户来说,他的下次访问或者下下次访问理应附带登录态。但是就我目前开发过的几个项目而言,微信内浏览器的cookie有几率丢失。而丢失登录态的用户则必须回到公众号页面通过点击tab的方式重新登录,这对用户来说成本太高,容易造成不必要的流失。

2. 用户信息盗用问题

在用户与公众号产生消息交互之后,公众号推送给用户的网址可能会附带用户的登录信息,在这种情况下任何人只要访问这个网址都可以获得该用户的数据。
实际上有一个hack解决方式。
1. 将推送给用户的网页设置成“图文消息”,让用户不可见网页具体链接地址;
2. 在用户访问网页之后使用JS清除网址上的登录信息(不保险,有几率无法清除);
3. 使用微信API干掉点击右上角后出现的“复制网页地址”、“在其他浏览器打开”的功能
4. 设置分享信息,将分享出去的网址上的用户信息擦除。

****

Thanks for Reading

Jiahao.Zhang
NetEase Inc. Hangzhou 
        Front-End Developer