uniapp 一键登录

官网文档地址https://uniapp.dcloud.net.cn/univerify.html

一、开发前准备

1、需要先开通uni一键登录服务

开通成功后会得到 apiKey、apiSecret。这2个信息,后续需要配置在uniCloud的云函数里。同时注意保密,这2个信息也是计费凭证

2、开通uniCloud服务

建议使用 阿里云服务空间 ~ 
然后可以开通前端网页托管功能,打包后的 安卓apk 包可以放在这里 或者 放在云储存里

3、勾选项目下manifest.json - App模块配置 - 一键登录

二、开发

概念说明:

虽然一键登录需要用到uniCloud,但并不要求开发者把所有的后台服务都迁移到uniCloud。

扫描二维码关注公众号,回复: 15719857 查看本文章

一键登录的代码完成是由前端来自己完成。后端只需要提供一个手机号登录的接口

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: 'xxx', // 在开发者中心开通服务并获取apiKey
		apiSecret: 'xxx', // 在开发者中心开通服务并获取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加密的方式,来保证该接口的安全性。

而不是由前端在 云函数返回手机号后 调用后端的登录接口~

猜你喜欢

转载自blog.csdn.net/qq_23375733/article/details/131479748