官网文档地址https://uniapp.dcloud.net.cn/univerify.html
一、开发前准备
1、需要先开通uni一键登录服务
开通成功后会得到 apiKey、apiSecret。这2个信息,后续需要配置在uniCloud的云函数里。同时注意保密,这2个信息也是计费凭证
2、开通uniCloud服务
建议使用 阿里云服务空间 ~
然后可以开通前端网页托管功能,后面打包后的 安卓apk 包的地址可以放在这里~
3、勾选项目下manifest.json - App模块配置 - 一键登录
二、开发
概念说明:
虽然一键登录需要用到uniCloud,但并不要求开发者把所有的后台服务都迁移到uniCloud。
一键登录的代码完成是由前端来自己完成。后端只需要提供一个手机号登录的接口
1、登录页示例代码
<template>
<view class="login-container">
<button v-if="isOneClickLogin" @click="oneClickLogin">一键登录</button>
<button v-else @click="oneSmsLogin">短信登录</button>
</view>
</template>
<script>
import { mapState } from 'vuex'
import store from '@/store'
export default {
data() {
return {
// 是否支持一键登录
isOneClickLogin: false
}
},
async onLoad() {
// 是否支持一键登录
await this.preLogin(true)
},
methods: {
// 一键登录
async oneClickLogin() {
await this.preLogin(true)
uni.login({
provider: 'univerify',
univerifyStyle: {
fullScreen: true,
backgroundColor: '#ffffff',
otherLoginButton: {
// 是否显示其他登录按钮
visible: false
},
authButton: {
normalColor: '#2dc8a1'
},
privacyTerms: {
// 条款勾选框初始状态
defaultCheckBoxState: false,
privacyItems: [{
url: 'https://xxx/agreement.html',
title: '用户服务协议'
},
{
url: 'https://xxx/privacypolicy.html',
title: '隐私政策'
}
]
}
},
success(res) {
uniCloud.callFunction({
name: 'login',
data: {
access_token: res.authResult.access_token,
openid: res.authResult.openid,
serversUrl: '这里上传你的接口地址'
}
}).then(async (dataRes) => {
if (dataRes.result.code == 0) {
// 这里写你登录成功后的逻辑 ...
uni.showToast({
title: '登录成功',
icon: 'success'
})
uni.setStorageSync('token', dataRes.result.data.access_token)
setTimeout(async () => {
uni.closeAuthView()
uni.navigateBack()
}, 1000)
} else {
uni.showToast({
title: dataRes.result.message,
icon: 'none'
})
}
}).catch((err) => {
uni.showModal({
title: '登录失败',
content: err.errMsg,
showCancel: false,
success() {
uni.closeAuthView()
}
})
})
},
fail(err) {
if (err.errCode != 30002 && err.errCode != '30003' && err.errCode != '30006') {
uni.showModal({
title: '登录失败',
content: err.errMsg,
showCancel: false,
success() {
// 客户端关闭一键登录授权界面
uni.closeAuthView()
}
})
}
}
})
},
/**
* 预登录
* 1、预登录操作可以判断当前设备环境是否支持一键登录,如果能支持一键登录,此时可以显示一键登录选项,同时预登录会准备好相关环境,显著提升显示授权登录界面的速度。
* 2、如果当前设备环境不支持一键登录,此时应该显示其他的登录选项。
* 3、如果手机没有插入有效的sim卡,或者手机蜂窝数据网络关闭,都有可能造成预登录校验失败。
* @param Boolean isShowMsg: 是否显示错误提示
*/
preLogin(isShowMsg = false) {
return new Promise((resolve, reject) => {
uni.preLogin({
provider: 'univerify',
success() {
this.isOneClickLogin = true
resolve(true)
},
fail(err) {
// 如果手机没有插入有效的sim卡,或者手机蜂窝数据网络关闭,都有可能造成预登录校验失败。
this.isOneClickLogin = false
if (isShowMsg && err.errMsg != 'login:ok') {
// 不同运营商 返回的报错字段不同
uni.showModal({
title: '当前设备环境不支持一键登录',
content: err.errMsg || err.metadata.resultMsg || err.metadata.error_data || err.metadata.resultDesc ||
'请检查是否插入有效sim卡及开启蜂窝数据网络',
showCancel: false
})
}
resolve(false)
}
})
})
},
// 短信登录
oneSmsLogin() {
// 跳转到短信登录页 ...
uni.navigateTo({
url: 'xxx'
})
}
</script>
<style lang="scss" scope></style>
2、uniClound login云函数代码
'use strict'
const crypto = require('crypto')
exports.main = async (event, context) => {
const res = await uniCloud.getPhoneNumber({
provider: 'univerify',
apiKey: '28f8c30ef63b8b977daffc3b896ad686', // 在开发者中心开通服务并获取apiKey
apiSecret: '72395110f43e516552e2e2fd4066e359', // 在开发者中心开通服务并获取apiSecret
access_token: event.access_token,
openid: event.openid
})
// 这里需要改成你们自己后端登录成功后的接口地址 ...
const url = event.serversUrl + '/auth/client/phoneLogin'
// md5加密方式:手机号 时间戳 私钥
const phone = res.phoneNumber
const timestamp = new Date().getTime()
const signKey = 'be6ff85f-20a1-76ce-f837-60933dca0975'
const sign = crypto.createHash('md5').update(phone + timestamp + signKey).digest('hex')
const result = await uniCloud.httpclient.request(url, {
method: 'POST',
data: {
phone,
timestamp,
sign
},
contentType: 'json',
dataType: 'json',
// 是否在证书不受信任时返回错误
rejectUnauthorized: false
})
console.log('服务端返回结果=', result)
if (result.data.code == 200) {
return {
code: 0,
message: '获取手机号成功',
data: result.data.data
}
} else {
return {
code: result.data.code,
message: result.data.msg,
data: result.data.data
}
}
}
目录结构如下:
注意:这个uniClound目录是跟我们前端代码放在一起的。云函数代码写完后需要上传部署到云服务空间。
这边为了安全性考虑。一键登录成功拿到手机号后 直接在云函数里调用后端接口,在进行md5加密的方式,来保证该接口的安全性。
而不是由前端在 云函数返回手机号后 调用后端的登录接口~