问题介绍
小程序登录及从解密数据中获取 UnionID等用到wx.getUserInfo接口,涉及到用户授权。登录还涉及到session_key,登录态是否过期问题。
用户授权
wx.getUserInfo接口调整说明:
在用户未授权过的情况下调用此接口,将不再出现授权弹窗,会直接进入 fail 回调(详见《公告》)。在用户已授权的情况下调用此接口,可成功获取用户信息。
为优化用户体验,使用 wx.getUserInfo 接口直接弹出授权框的开发方式将逐步不再支持。开发者可使用 button 组件,并将 open-type 指定为 getUserInfo 类型,获取用户基本信息。
开发者可以使用 wx.getSetting 获取用户当前的授权状态。
部分接口需要获得用户授权同意后才能调用。此类接口调用时:
- 如果用户未接受或拒绝过此权限,会弹窗询问用户,用户点击同意后方可调用接口;
- 如果用户已授权,可以直接调用接口;
- 如果用户已拒绝授权,则不会出现弹窗,而是直接进入接口 fail 回调。请开发者兼容用户拒绝授权的场景。
登录态过期
会话密钥 session_key 有效性
开发者如果遇到因为 session_key 不正确而校验签名失败或解密失败,请关注下面几个与 session_key 有关的注意事项。
- wx.login 调用时,用户的 session_key 可能会被更新而致使旧 session_key 失效(刷新机制存在最短周期,如果同一个用户短时间内多次调用 wx.login,并非每次调用都导致 session_key刷新)。开发者应该在明确需要重新登录时才调用 wx.login,及时通过 auth.code2Session 接口更新服务器存储的session_key。
- 微信不会把 session_key 的有效期告知开发者。我们会根据用户使用小程序的行为对 session_key 进行续期。用户越频繁使用小程序,session_key 有效期越长。
- 开发者在 session_key 失效时,可以通过重新执行登录流程获取有效的 session_key。使用接口 wx.checkSession可以校验 session_key 是否有效,从而避免小程序反复执行登录流程。
- 当开发者在实现自定义登录态时,可以考虑以 session_key 有效期作为自身登录态有效期,也可以实现自定义的时效性策略。
注意:
- session_key和微信派发的code是一一对应的,同一code只能换取一次session_key。每次调用wx.login(),都会下发一个新的code和对应的session_key,为了保证用户体验和登录态的有效性,开发者需要清楚用户需要重新登录时才去调用wx.login()
- session_key是有时效性的,即便是不调用wx.login,session_key也会过期,过期时间跟用户使用小程序的频率成正相关,但具体的时间长短开发者和用户都是获取不到的
解决问题
写一个授权登录页面,默认首页就是授权页面,需要登录的时候也跳转这个页面。在授权页面判断不同需要登录的情况。
authorization.wxml
<!--authorization.wxml-->
<view class="container">
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
<view class='content'>
<view>小程序申请获取以下权限</view>
<text>获得你的公开信息(昵称,头像等)</text>
</view>
<view class="userinfo">
<button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo"> 微信授权登录 </button>
<view wx:else>请升级微信版本</view>
</view>
</view>
authorization.wxss
/**authorization.wxss**/
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
}
.usermotto {
margin-top: 0rpx;
}
.content {
margin-top: 100rpx;
margin-bottom: 90rpx;
}
.content text {
font-size: medium;
display: block;
color: #9d9d9d;
margin-top: 40rpx;
}
authorization.js
//authorization.js
const util = require('../../utils/util.js')
Page({
data: {
motto: '进行此操作需要进行用户授权',
canIUse: wx.canIUse('button.open-type.getUserInfo')
},
onLoad: function () {
console.log('当前页' + getCurrentPages()[getCurrentPages().length - 1].route)
wx.checkSession({
success: function (e) { //登录态未过期
console.log("没过期");
// 查看是否授权
wx.getSetting({
success: function (res) {
if (res.authSetting['scope.userInfo']) { //已授权
if (wx.getStorageSync('sessionId')) { //storage中有‘sessionId’
//转到首页
wx.redirectTo({
url: '../home/home',
})
} else { //情况1:storage中没有‘sessionId’,重新登录
util.login();
}
}
}
})
},
fail: function () { //情况2:登录态过期了,需重新登录
console.log("过期了");
// 查看是否授权
wx.getSetting({
success: function (res) {
if (res.authSetting['scope.userInfo']) {
util.login();
}
}
})
},
})
},
//授权弹窗操作 情况3:用户未授权,需点击button授权
bindGetUserInfo: function (e) {
if (e.detail.userInfo) { //用户按了允许授权按钮
// 登录操作
util.login();
} else { //用户按了拒绝按钮
wx.showModal({
title: '警告',
content: '您点击了拒绝授权,将无法进入小程序,请授权之后再进入~',
showCancel: false,
confirmText: '我知道了',
success: function (res) {
if (res.confirm) {
console.log('用户点击了“我知道了”')
//返回前一页面
wx.navigateBack({
delta: 1
})
}
}
})
}
},
})