1. 前端调用 wx.login 获取code
2. 前端将code发送至后端,后端结合小程序的appkey+appSecret,调用 code2session 获取openid+session_key
注意:如果用户有关注跟小程序有相同主体的公众号(服务号),那么此时也能够获取用户的unionId。这就是微信开发文档中提到的满足条件。
备注:在一定程度上,openId也足够用(单小程序,不给用户发送消息),否则的话最好获取一下用户的unionId
3. 因为后端通过 code2session api接口有可能获取不到unionId,此时前端可以通过用户授权的方式调用 getUserInfo 接口,获取用户信息及加密的unionId数据(加密数据-encryptedData,偏移量-iv,用户信息-userInfo及其他数据)
4. 前端将从该接口获取的数据统一传给后端,后端根据微信提供的解密方式,使用之前 code2session 获取到的session_key + iv 对encryptedData解密。
5. 解密数据会包含当前微信用户的unionId,有人说也能获取到手机号,但是本人在实践中并没有获取到,而且根据微信提供的文档显示,获取手机号需要用户触发操作才能获取,详见:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
解密过程也有许多坑,详见下述。
首先贴一下流程图,来自微信开发文档:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
// 从前端参数中获取code
String js_code = params.getString("code");
String grant_type = "authorization_code";
String appid = "小程序APPId";
String secret = "小程序APPSecret";
// 后端通过发送Http - GET 请求,换取 用户唯一标识 OpenID 和 会话密钥 session_key
GET https://api.weixin.qq.com/sns/jscode2session?appid=appid&secret=secret&js_code=js_code&grant_type=grant_type
// 返回结果 这样子
{"session_key":"session_key==","openid":"openid"}
// 如果用户也关注了与小程序同主体的公众号,那么还能够获取到unionid,这样子
{"session_key":"session_key==","openid":"openid","unionid":"unionid"}
// 前端调用 getUserInfo 接口获取到的数据(我不是前端,就只贴一下前端给我的数据)
// 详情可参考:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserInfo.html
{
"userInfo":
{
"nickName":"nickname",
"gender":1,
"language":"zh_CN",
"city":"city",
"province":"Beijing",
"country":"China",
"avatarUrl":"avatarUrl"},
"code":"临时登录凭证code",
"signature":"signature-没注意是干啥的",
"encryptedData":"加密的用户信息数据",
"rawData":"这个字段就是userInfo的数据"}",
"iv":"初始向量,也成为偏移量"
}
详细解密流程参考:https://blog.csdn.net/weixin_42346767/article/details/102509429
// 详细解密逻辑代码在此不赘述,另开博客
// 地址:https://blog.csdn.net/weixin_42346767/article/details/102509429
// 解密后的数据格式跟userInfo类似,但略有偏差
{
"country":"China",
"unionId":"我的unionId",
"watermark":{"appid":"appid","timestamp":1570783572},
"gender":1,
"province":"Beijing",
"city":"Haidian",
"avatarUrl":"帅气头像",
"openId":"openId",
"nickName":"有点过分,但是",
"language":"zh_CN"
}
// 相比前端提供的userInfo数据,这部分多了watermark数据和unionId
浅薄之见,也不知道是否还符合主流设计,如有更好的方式建议,欢迎留言交流,谢谢~
其他参考文章:
1. 微信小程序登录(包括获取不到unionid的情况)
https://www.cnblogs.com/yaoyuqian/p/8203792.html
2. 从微信用户加密数据encryptedData获取用户信息userInfo和unionId
https://blog.csdn.net/weixin_42346767/article/details/102509429
3. 关于微信小程序登陆怎么获取UnionIdJAVA版本
https://blog.csdn.net/weixin_40992563/article/details/80973698