官网文档地址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 = trueresolve(true)},fail(err) {// 如果手机没有插入有效的sim卡,或者手机蜂窝数据网络关闭,都有可能造成预登录校验失败。this.isOneClickLogin = falseif (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: 'xxx', // 在开发者中心开通服务并获取apiKeyapiSecret: 'xxx', // 在开发者中心开通服务并获取apiSecretaccess_token: event.access_token,openid: event.openid})// 这里需要改成你们自己后端登录成功后的接口地址 ...const url = event.serversUrl + '/auth/client/phoneLogin'// md5加密方式:手机号 时间戳 私钥const phone = res.phoneNumberconst 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加密的方式,来保证该接口的安全性。
而不是由前端在 云函数返回手机号后 调用后端的登录接口~