“这是我参与更文挑战的第6天,活动详情查看: 更文挑战”
前言
最近,开发一个系统时要采用扫微信小程序码来注册或登录,为什么要扫微信小程序码,而不是扫微信公众号二维码。是因为该系统的用户必须绑定手机号才能使用系统。而在微信公众号中无法获取微信用户绑定的手机号。只有在微信小程序中才可以获取到微信用户绑定的手机号。
1、业务流程图
先上一下业务流程图,后面介绍一下关键步骤的实现。
1、扫码登录后Web端系统如何知道
假设进入Web端系统登录页面时,向服务端请求小程序码时,可以返回一个唯一的小程序码,并且返回一个唯一标识key。当用微信扫小程序码进入小程序又能获取到这个唯一标识key,调用wx.login登录后,把返回的小程序登录凭证code和key,一起发送给服务端。
同时在Web端系统登录页用中用定时器发起一个轮询,不断用key向服务端询问这个浏览器打开的Web端系统是否登录成功。
这样服务端就可以通过这个唯一标识key和要登录系统的浏览器建立起一一映射的关系。
那么用来登录的小程序码时动态的,要如何获取呢?
2、动态小程序码如何获取
通过小程序服务端APIwxacode.getUnlimited来获取,具体使用文档点这里。在获取中要注意以下几点。
-
先获取
access_token,access_token是小程序全局唯一后台接口调用凭据,为了access_token的安全性,服务端API不能直接在小程序内通过wx.request调用。调用服务端APIauth.getAccessToken,其中参数appid小程序唯一凭证和secret小程序唯一凭证密钥,是要微信小程序开发者去小程序后台设置。 -
参数
scene是要设置成唯一标识key,因为参数scene的值有规则限制,所以key也必须符合该规则,具体规则如下所示:最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
-
参数
page,设置生成小程序码,扫码后进入的页面。必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index, 根路径前不要填加/,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面。
3、从小程序码中获取唯一标识key
使用onLoad生命周期函数获取,其参数可以接收路径上定义的参数。
Page({
onLoad (query) {
// scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
const scene = decodeURIComponent(query.scene)
}
})
4、如何用小程序登录系统
在小程序中有一个用户唯一标识openid,可以用openid作为系统用户的唯一标识。那么如何获取小程序用户唯一标识openid呢?
执行wx.login获取小程序登录凭证code,将code和key发送给服务端发起登录请求,服务端调用小程序服务端APIauth.code2Session解析code获取小程序用户的openid。
Page({
onLoad(query){
wx.login({
success: res => {
const code = res.code; //小程序登录凭证
},
})
}
})
通过openid去查用户表,若用户表中有该openid的数据,且该条数据有手机号,那么等Web端系统下次使用唯一标识key,询问服务端是否登录成功时,就可以告诉Web端系统已经登录成功。
若该条数据没有手机号,则代表未注册,走注册流程,注册中得用到用户绑定的手机号,那么如何获取小程序用户绑定手机号呢?
5、获取小程序用户绑定手机号
在小程序必须通过用户点击button组件才能调其获取用户手机号的授权,button组件上增加open-type=getPhoneNumber属性设置,且用bindgetphonenumber监听获取用户手机号授权的回调。
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">
微信用户快速注册
</button>
Page({
getPhoneNumber (e) {
console.log(e.detail.iv)
console.log(e.detail.encryptedData)
}
})
getPhoneNumber会得到两个数据。iv加密算法的初始向量,encryptedData用户私密信息的加密数据,
把iv和encryptedData发送给服务端,服务端在对其解密,在解密的过程会用到之前解析小程序登录凭证code,获取的session_key会话密钥。
wx.login调用时,用户的session_key可能会被更新而致使旧session_key失效,由于刷新机制存在最短周期,如果同一个用户短时间内多次调用wx.login,并非每次调用都导致session_key刷新。开发者应该在明确需要重新登录时才调用wx.login,及时通过auth.code2Session接口更新服务器存储的 session_key。防止session_key失效导致解密失败。
服务端解密后直接把手机号存入对应的用户信息数据中,此时注册成功,等Web端系统下次使用唯一标识key,询问服务端是否登录成功时,就可以告诉Web端系统已经登录成功。
6、开发过程如何调试
在调用小程序服务端APIwxacode.getUnlimited获取动态小程序码时,其参数page必须是已经发布的小程序存在的页面,所以在开发阶段一般参数page是不填的,默认是小程序的首页。在根目录下app.json中pages项的第一个路径对应的页面就是小程序的首页。
在开发时,可以把生成的小程序码保存到电脑上,在微信开发者工具中使用二维码编译模式,进入小程序页面调试。