隐私协议授权的一种解决思路
现状
登录页使用了获取手机号接口,登录页为单独的页面(非弹窗),所有登录需求都会跳转到此页。
[图片]
分析
小程序提供两种接入方式:一种是主动查询授权状态,如果状态为未授权则进入授权流程,已授权则无需处理;另一种是被动监听何时需要授权,触发事件后进入授权流程,未触发则表示已授权。在登录的流程中,主动查询就是先发起授权后点击登录按钮,被动监听就是先点击登录按钮后发起授权。个人感觉,主动查询的方式先告知用户需要采集隐私数据,比较符合用户习惯,而被动监听的方式事前未告知用户需要授权,且打断了登录的流程,用户体验不佳,因此采取主动查询的方式。
官方的示例采用了弹窗授权的方式,但无论是在页面上覆盖一个模拟弹窗组件,还是使用page-container,控制弹窗都不能像VUE那样优雅,复用也不方便。鉴于登录页也是单独的页面,考虑到以后可能还有其它页面需要授权,因此授权页也采用单独的页面(PS.skyline的自定义路由可以很优雅地实现弹窗,但目前还没有适配,暂不考虑,之后对授权页进行改造即可)。
思路
在登录页的onLoad中主动查询授权状态,如果状态为未授权则调用授权接口跳转到授权页,授权页回调授权状态,如果授权失败则登录也失败。
[图片]
实现
[代码]// 封装的登录接口
function requestLogin() {
return new Promise(async (resolve, reject) => {
wx.navigateTo({
url: '/pages/user/user-login/user-login', // 登录页
events: {
login: (loginStatus) => {
// 登录状态回调
if (loginStatus) {
// 成功
resolve()
} else {
// 失败
reject(new Error('login fail'))
}
}
},
fail: () => reject(new Error('navigate fail'))
})
})
}
// 封装的授权接口
function requestProvicy() {
return new Promise(async (resolve, reject) => {
wx.getPrivacySetting({
success: (res) => {
if (res.needAuthorization) {
// 需要授权
wx.navigateTo({
url: '/pages/user/user-login/user-login', // 登录页
events: {
privacy: (privacyStatus) => {
// 授权状态回调
if (loginStatus) {
// 成功
resolve()
} else {
// 失败
reject(new Error('privacy fail'))
}
}
},
fail: () => reject(new Error('navigate fail'))
})
} else {
// 无需授权
resolve()
}
},
fail: () => reject(new Error('get privacy fail'))
})
})
}
// 第一步:调用封装的登录接口
// 需要登录才能进入的页面
Page({
onLoad: async function(options) {
try {
await wx.$auth.requestLogin() // 登录失败抛出错误
} catch {
return wx.$router.back() // 返回上一页
}
// 业务代码
}
})
// 第二步:获取手机号登录
// 登录页
<!-- wxml >
<button open-type="getPhoneNumber" bindgetphonenumber="handleGetPhoneNumber">获取手机号</button>
Page({
handleGetPhoneNumber: async function(e) {
const code = e.detail.code // 手机号code
// 调用自己后台的登录接口
this._loginStatus = true // 登录成功状态,在onUnload回调
wx.$router.back() // 返回上一页
},
onLoad: async function() {
try {
await wx.$auth.requestProvicy() // 授权失败抛出错误
} catch {
return wx.$router.back() // 返回上一页
}
}
onUnload: function() {
const eventChannel = this.getOpenerEventChannel()
if (!eventChannel) return
eventChannel.emit('login', !!this._loginStatus) // 回调登录结果
}
})
// 第三步:授权
// 授权页
<!-- wxml >
<button id="agree-btn" open-type="agreePrivacyAuthorization" bindagreeprivacyauthorization="handleAgreePrivacyAuthorization">我已阅读并同意隐私协议</button>
Page({
handleAgreePrivacyAuthorization: async function() {
this._privacyStatus = true // 授权成功状态,在onUnload回调
wx.$router.back() // 返回上一页
},
onUnload: function() {
const eventChannel = this.getOpenerEventChannel()
if (!eventChannel) return
eventChannel.emit('privacy', !!this._privacyStatus) // 回调登录结果
}
})
[代码]
最终效果
未登录的状态下打开一个需要登录才能使用的页面
[图片]
可以进入小程序实际体验一下,欢迎各位一起讨论
[图片]