IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> uniapp + vue3微信小程序开发(3)微信授权登录 -> 正文阅读

[移动开发]uniapp + vue3微信小程序开发(3)微信授权登录

整体思路:

接口获取openId => 用户微信信息入库 => 手机号授权入库

逻辑详解:

我们知道小程序都是需要openId的,那我们可以通过前端获取,也可以通过后端接口获取,

前端就是这个地址,appid和secret 在你微信公众平台下都可以找到, code,在你调用uni.login就可以获取,但是切记,code码只能使用一次,你在开发环境时可以使用下面链接来前端获取openId,但是在线上生产环境,就要切换成后端接口获取了,因为会被小程序服务器域名所限制。

https://api.weixin.qq.com/sns/jscode2session?appid=' +
						appid + '&secret=' + secret + '&js_code=' + code +
						'&grant_type=authorization_code

获取到openId的目的,就是判断你数据库里是否有该用户,在小程序里,openId就是唯一主键的意思,然后下一步就是获取你的微信昵称和头像,那么这个要调用

uni.getUserProfile()

大家一定要用这个api来获取微信信息,否则其他获取的是假的用户信息 !

获取手机号授权,这个必须要求你在微信公众平台申请哦,否则是没有这个权限的,另外大家可能有疑问,微信信息授权和手机号授权为啥不写在一起? 因为手机号授权只能通过button按钮,并且使用open-type来获取,这一点,uniapp和微信原生是一致的,而且这个获取手机号的按钮,必须用户主动去点击喔,所以这也是我为啥将他写在遮盖层上了。

 <button  type="primary"  open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">绑定手机号</button>

手机号和微信用户信息这样都拿到了,那你就可以完成自己想要的操作了,那么又有同学想问,那我想获取身份证信息咋办? 那我明确告诉你,取不到!那有没有类似的呢,可以通过百度ocr识别来将前端传上去的身份证照片进行验证识别,这一点,我下一篇博客将会写上去?。

部分截图:

点击授权登录,将会弹出微信用户信息授权,然后会出现获取手机号按钮的遮盖层,点击获取手机号授权

?

?

所有代码:

这里简单说一下, proxy.$api.user.xxx, 这是我调用接口的方式,大家可以根据自己想要方式来实现uni.request,这一点没有啥强制性要求

<template>
	<view>
		<view>
			<view>
				<view class="header">
					<image src="/static/img/login-wx.png"></image>
				</view>
				<view class="content">
					<view>申请获取以下权限</view>
					<text>获得你的公开信息(昵称,头像、地区等)</text>
				</view>
				<button class="bottom" type="primary" :disabled="userInfoDisabled" @click="wxGetUserInfo">授权登录</button>
			</view>
		</view>
		<van-overlay :show="overlayShow">
		  <view class="login-wrapper">
			  <view class="login-bottom">
					 <button  type="primary"  open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">绑定手机号</button>
			  </view>
		  </view>
		</van-overlay>
	</view>
</template>

<script setup>
	import {
		ref,
		reactive,
		getCurrentInstance
	} from 'vue'
	import {
		onLoad
	} from '@dcloudio/uni-app'

	const {
		proxy
	} = getCurrentInstance()
	const appid = "xxx"
	const secret = "xxx"
	const userInfoDisabled = ref(false)
	const userInfo = reactive({
		thirdAppType: 1,
		thirdUserId: "",
		nickName: '',
		wechatPicture: ''
	})
	const sessionKey = ref('') // session码
	const pageOption = ref()
	const overlayShow = ref(false)
	const wxGetUserInfo = () => {
		if (uni.getUserProfile) {
			uni.getUserProfile({
				desc: 'Wexin', // 这个参数是必须的
				success: result => {
					uni.showLoading({
						title: '授权中...'
					});
					userInfoDisabled.value = true
					userInfo.nickName = result.userInfo.nickName
					userInfo.wechatPicture = result.userInfo.avatarUrl
					proxy.$api.user.login({
						thirdAppType: userInfo.thirdAppType,
						thirdUserId: userInfo.thirdUserId,
						nickName: userInfo.nickName,
						wechatPicture: userInfo.wechatPicture
					}).then(res => {
						userInfoDisabled.value = false
						uni.hideLoading();
						if (res.data.bindSpecialCode == 203) {
							uni.setStorageSync('id', res.data.id);
							uni.setStorageSync('nickName', res.data.nickName);
							uni.setStorageSync('wechatPicture', res.data.wechatPicture);
							overlayShow.value = true
							return
						} else {
							uni.showToast({
								title: '登录成功'
							})
							uni.setStorageSync('id', res.data.id);
							uni.setStorageSync('nickName', res.data.nickName);
							uni.setStorageSync('wechatPicture', res.data.wechatPicture);
							uni.setStorageSync('tel', res.data.tel.data);
							// 然后跳回原页面
							if (pageOption.value.backtype == 1) {
								uni.redirectTo({
									url: '/pages/home/index'
								})
							} else {
								uni.switchTab({
									url: '/pages/home/index'
								})
							}
						}
					}).catch(e => {
						userInfoDisabled.value = false
						uni.hideLoading();
						uni.showToast({
							title: '用户信息操作失败',
							icon: 'none'
						});
					})
				},
				fail: res => {
					console.log('用户拒绝授权信息');
				}
			})
		} else {
			uni.showToast({
				title: '获取用户信息失败',
				icon: 'none'
			});
		}
	}

	const login = () => {
		uni.showLoading({
			title: '登录中...'
		});
		uni.login({
			provider: 'weixin',
			success: loginRes => {
				let code = loginRes.code;
				proxy.$api.user.getOpenId({
					appid,
					secret,
					code
				}).then(res => {
					if (res.code == 200) {
						getOpenId(res.data)
					}
				}).catch(e => {
					uni.hideLoading();
					uni.showToast({
						title: '获取 OpenId 失败',
						icon: 'none'
					});
					userInfoDisabled.value = false
				})
			},
			fail: () => {
				uni.hideLoading();
				uni.showToast({
					title: '获取 code 失败',
					icon: 'none'
				});
				userInfoDisabled.value = false
				return false;
			}
		});
		return false;
	}
	const getOpenId = (codeRes) => {
		let openId = codeRes.openid;
		sessionKey.value = codeRes.sessionKey;
		userInfo.thirdUserId = openId	
		proxy.$api.user.openIdParse({
			thirdAppType: userInfo.thirdAppType,
			thirdUserId: openId
		}).then(res => {
			uni.hideLoading();
			uni.setStorageSync('openId', openId);
			userInfoDisabled.value = false
			// 用户信息未授权入库
			if (res.data.bindSpecialCode == 202) {
				uni.showToast({
					title: '请点击授权登录',
					icon: 'none'
				});
			// 用户手机号未授权入库
			} else if (res.data.bindSpecialCode == 203) {
				overlayShow.value = true
				uni.setStorageSync('id', res.data.id);
				uni.setStorageSync('nickName', res.data.nickName);
				uni.setStorageSync('wechatPicture', res.data.wechatPicture);
			} else {
				uni.showToast({
					title: '登录成功'
				})
				uni.setStorageSync('id', res.data.id);
				uni.setStorageSync('nickName', res.data.nickName);
				uni.setStorageSync('wechatPicture', res.data.wechatPicture);
				uni.setStorageSync('tel', res.data.tel.data);
				if (pageOption.value.backtype == 1) {
					uni.redirectTo({
						url: '/pages/home/index'
					})
				} else {
					uni.switchTab({
						url: '/pages/home/index'
					})
				}
			}
		}).catch(e => {
			uni.hideLoading();
			uni.showToast({
				title: '获取授权信息失败',
				icon: 'none'
			});
			userInfoDisabled.value = false
		})
	}
	/**
	 * 手机号授权
	 */
	const getPhoneNumber = (e) => {
	    if (e.detail.errMsg == 'getPhoneNumber:fail user deny') {
	        console.log('用户拒绝提供手机号');
	    } else {
	        let encryptedData = e.detail.encryptedData
	        let iv = e.detail.iv
			overlayShow.value = false
			if (encryptedData && iv) {
				bindTelApi(encryptedData, iv)
			}
	    }
	}
	const bindTelApi = (encryptedData, iv) => {
		uni.showLoading({
			title: '绑定手机号中...'
		});
		proxy.$api.user.bindTel({
			 encryptedData: encryptedData,
			 iv: iv,
			 sessionKey: sessionKey.value,
			 uid: uni.getStorageSync('id')
		}).then(res => {
			uni.hideLoading()
			if (res.code == 200) {
				uni.setStorageSync('tel', res.data.tel.data);
				uni.switchTab({
					url: '/pages/home/index'
				})
			}
		}).catch(e => {
			uni.hideLoading()
		})
	}
	onLoad((options) => {
		pageOption.value = options
		const {
			proxy
		} = getCurrentInstance()
		const loginStatus = proxy.checkLogin('/pages/home/index', 2)
		if (!loginStatus) {
			userInfoDisabled.value = true
			login();
		} else {
			uni.switchTab({
				url: '/pages/home/index'
			})
		}
	})
</script>
<style lang="scss" scoped>
	.header {
		margin: 160rpx 0 60rpx 50rpx;
		text-align: center;
		width: 650rpx;

		image {
			width: 180rpx;
			height: 180rpx;
		}
	}

	.content {
		margin-bottom: 68rpx;
		text-align: center;

		text {
			display: block;
			color: #9d9d9d;
			margin-top: 20rpx;
		}
	}

	.bottom {
		border-radius: 80rpx;
		margin: 70rpx 50rpx;
		font-size: 35rpx;
	}
	.login-wrapper{
		height: 100%;
		position: relative;
		.login-bottom{
			position: absolute;
			bottom: 0;
			left: 0;
			width: 100%;
			height: 133rpx;
			background-color: #fff;
			button{
				position: absolute;
				top: 50%;
				left: 50%;
				background-color: #CA2915;
				transform: translate(-50%, -50%);
				border-radius: 30px;
				width: 435rpx;
				height: 68rpx;
				line-height: 68rpx;
			}
		}
	}
</style>

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:51:06  更:2022-05-09 12:52:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:45:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码