uniCloud学习笔记---uniId

一.uni-id公用模块环境配置

uni_modules版

1.插件市场导入uni-id公用模块uni_modules版本
2.在uni-config-center公用模块下创建uni-id目录,在uni-id目录下再创建config.json文件配置
uni_modules\uni-config-center\uniCloud\cloudfunctions\common\uni-config-center\uni-id\config.json
…\uniCloud\cloudfunctions\common\uni-config-center\uni-id\config.json
在这里插入图片描述
在这里插入图片描述

3.cloudfunctions/common文件上传更新
4.在要使用uni-id的云函数右键选择管理公共模块依赖添加uni-id到云函数,添加依赖后需要重新上传该云函数
5.创建uni-id-users、opendb-verify-codes等集合,也可以在云控制台创建

config.json是一个标准json文件,不支持注释

{
	"passwordSecret": "passwordSecret-demo",
	"tokenSecret": "tokenSecret-demo",
	"tokenExpiresIn": 7200,
	"tokenExpiresThreshold": 600,
	"bindTokenToDevice": false,
	"passwordErrorLimit": 6,
	"passwordErrorRetryTime": 3600,
	"autoSetInviteCode": false,
	"forceInviteCode": false,
	"removePermissionAndRoleFromToken": false,
	"app-plus": {
		"tokenExpiresIn": 2592000,
		"oauth": {

			"weixin": {
				"appid": "weixin appid",
				"appsecret": "weixin appsecret"
			},

			"qq": {
				"appid": "qq appid",
				"appsecret": "qq appsecret"
			},
			"apple": {
				"bundleId": "your bundleId"
			}
		}
	},
	"mp-weixin": {
		"tokenExpiresIn": 259200,
		"oauth": {

			"weixin": {
				"appid": "weixin appid",
				"appsecret": "weixin appsecret"
			}
		}
	},
	"mp-qq": {
		"tokenExpiresIn": 259200,
		"oauth": {

			"qq": {
				"appid": "qq appid",
				"appsecret": "qq appsecret"
			}
		}
	},
	"mp-alipay": {
		"tokenExpiresIn": 259200,
		"oauth": {

			"alipay": {
				"appid": "alipay appid",
				"privateKey": "alipay privateKey",
				"keyType": "PKCS8"
			}
		}
	},
	"service": {
		"sms": {
			"name": "your app name",
			"codeExpiresIn": 180,
			"smsKey": "your sms key",
			"smsSecret": "your sms secret"
		},
		"univerify": {
			"appid": "your appid",
			"apiKey": "your apiKey",
			"apiSecret": "your apiSecret"
		}
	}
}

二.持久化保存token及其过期时间

开发者应在用户登录/注册成功后持久化保存token及其过期时间。同样的在用户登出之后应删除保存的token及其过期时间。

客户端保存token及其有效期
在用户登录/注册成功后应在storage内保存用户的token及其过期时间,示例代码如下:
按照以下格式保存的token,在调用云函数的时候会自动携带.

uni.setStorageSync('uni_id_token', token)
uni.setStorageSync('uni_id_token_expired', tokenExpired)

客户端删除token及其有效期
在用户登出成功之后应删除持久化存储的token及其过期时间,示例代码如下:

uni.removeStorageSync('uni_id_token')
uni.removeStorageSync('uni_id_token_expired')

三.index.vue+云函数userCenter实现注册\登录\改密等操作

在这里插入图片描述

// 云函数userCenter的代码
const uniID = require('uni-id')
const uniCaptcha = require("uni-captcha")
exports.main = async function(event, context) {
	let res = {}
	let release = ["register", "login", "logout", "createCaptcha", "verifyCaptcha", "refreshCaptcha"];//不需要token验证的操作
	let payload = {}
	let {
		uniIdToken,//客服端提交的时候会自动携带  格式:uni_id_token;uni_id_token_expired
		action,
		param
	} = event
	param = param ? param : {}
	if (release.indexOf(action) === -1) {
		if (!uniIdToken) {
			res = {
				code: "740",
				msg: "缺少token"//阻止未登录或者token过期的操作
			}
			return res
		}
		payload = await uniID.checkToken(uniIdToken)
		if (payload.code === 0) {
			console.log("token校验通过"); //payload.uid
			param.uid = payload.uid
		} else {
			console.log("token校验未通过");//阻止未登录或者token过期的操作
			return payload
		}
	}
	switch (action) {
		case "createCaptcha":
			res = await uniCaptcha.create(param)
			break;
		case "verifyCaptcha":
			res = await uniCaptcha.verify(param)
			break;
		case "refreshCaptcha":
			res = await uniCaptcha.refresh(param)
			break;
		case "register":
			res = await uniID.register(param)
			break;
		case "login":
			res = await uniID.login(param)
			break;
		case "logout":
			res = await uniID.logout(uniIdToken)
			break;
		case "modifyPW":
			res = await uniID.updatePwd(param);
			break;
		case "modifyAvatar":
			res = await uniID.setAvatar(param)
			break;
		case "modifyNickname":
			res = await uniID.updateUser(param)
			break;
		case "getUserInfo":
			res = await uniID.getUserInfo(param)
			break;
		default:
			res = {
				code: "433",
				msg: "请求非法"//过滤非法请求
			}
	}
	return res
}

<template>
	<view class="content">
		<image class="avatarImg" :src="formData.avatar" mode="aspectFill"></image>
		<text>{{nickname}}</text>
		<uni-easyinput v-model="formData.username" placeholder="用户名" />
		<uni-easyinput v-model="formData.password" placeholder="密码" />
		<view class="captchaImgBox">
			<uni-easyinput style="margin-top: 6rpx;" v-model="captcha" placeholder="请输入验证码" />
			<image class="captchaImg" :src="formData.captcha" mode="aspectFit" @click="refreshCaptcha()">
			</image>
		</view>

		<uni-easyinput v-model="formData.newpassword" placeholder="新密码" />
		<uni-easyinput v-model="formData.nickname" placeholder="昵称" />
		<button type="default" @click="submit('register')">注册</button>
		<button type="default" @click="submit('login')">登录</button>
		<button type="default" @click="submit('logout')">退出</button>
		<button type="default" @click="submit('modifyPW')">修改密码</button>
		<button type="default" @click="submit('modifyAvatar')">修改头像</button>
		<button type="default" @click="submit('modifyNickname')">修改昵称</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				nickname: "nickname",
				captcha: "", //验证码文本
				formData: {
					username: "",
					password: "",
					newpassword: "",
					nickname: "",
					gender: 1, //男1 女2
					mobile: "",
					email: "",
					avatar: "",
					comment: "",
					captcha: "" //图片数据
				}
			}
		},
		onLoad() {},
		onReady() {
			this.createCaptcha()
		},
		methods: {
			createCaptcha() {
				uniCloud.callFunction({
					name: "userCenter",
					data: {
						action: "createCaptcha",
						param: {
							scene: "login",
							noise: 0
						}
					}
				}).then(e => {
					// console.log(e)
					this.formData.captcha = e.result.captchaBase64
				})
			},
			refreshCaptcha() {
				uniCloud.callFunction({
					name: "userCenter",
					data: {
						action: "refreshCaptcha",
						param: {
							scene: "login",
							noise: 0
						}
					}
				}).then(e => {
					// console.log(e)
					this.formData.captcha = e.result.captchaBase64
					this.captcha = ""
				})
			},
			async verifyCaptcha() {
				return await uniCloud.callFunction({
					name: "userCenter",
					data: {
						action: "verifyCaptcha",
						param: {
							scene: "login",
							captcha: this.captcha
						}
					}
				})
			},
			req(action, param) {
				return new Promise((resolve, reject) => {
					uniCloud.callFunction({
						name: "userCenter",
						data: {
							action,
							param
						},
						success: (e) => {
							resolve(e.result)
						},
						fail: (e) => {
							resolve(e)
						}
					})
				})
			},
			async submit(action) {
				uni.showLoading({})
				console.log(action);
				let res = {}
				switch (action) {
					case "register":
						res = await this.verifyCaptcha()
						console.log(res.result.code === 0 ? "注册成功" : res.result.msg);
						if (!res.result.code) {
							res = await this.req(action, {
								username: this.formData.username,
								password: this.formData.password
							})
						}
						this.refreshCaptcha()
						break;
					case "login":
						res = await this.verifyCaptcha()
						console.log(res);
						console.log(res.result.code === 0 ? "登录成功" : res.result.msg);
						if (res.result.code === 0) {
							res = await this.req(action, {
								username: this.formData.username,
								password: this.formData.password
							})
							if (res.code === 0) {
								uni.setStorageSync('uni_id_token', res.token)
								uni.setStorageSync('uni_id_token_expired', res.tokenExpired)
								this.req("getUserInfo", {
									fields: ["nickname", "avatar"]
								}).then(e => {
									this.formData.avatar = e.userInfo.avatar
									this.nickname = e.userInfo.nickname
								}).catch(err => {
									console.log(err);
								})
							}
						} 
						this.refreshCaptcha()
						break;
					case "logout":
						res = await this.req(action, {
							username: this.formData.username,
							password: this.formData.password,
						})
						console.log(res.code === 0 ? "退出成功" : res.errMsg);
						this.formData.avatar = "",
							this.nickname = "nickname"
						break;
					case "modifyPW":
						res = await this.req(action, {
							username: this.formData.username,
							oldPassword: this.formData.password,
							newPassword: this.formData.newpassword
						})
						console.log(res.code === 0 ? "密码修改成功" : res.errMsg);
						break;
					case "modifyAvatar":
						res = await uniCloud.chooseAndUploadFile({
							count: 1,
							type: "image",
						}).then(e => {
							let url = e.tempFiles[0].url
							console.log(url);
							this.formData.avatar = url
							this.req(action, {
									avatar: this.formData.avatar
								})
								.then(e => {
									console.log(e.code === 0 ? "头像修改成功" : e.errMsg);
								}).catch(err => {
									console.log(err);
								})
						}).catch(err => {
							console.log(err);
						})
						break;
					case "modifyNickname":
						res = await this.req(action, {
							nickname: this.formData.nickname
						})
						console.log(res.code === 0 ? "昵称修改成功" : res.errMsg);
						if (res.code === 0) {
							this.nickname = this.formData.nickname
						}
						break;
					default:
						console.log("default");
				}
				uni.hideLoading()
			}
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}

	.avatarImg {
		width: 250rpx;
		height: 270rpx;
		border: #007AFF solid 1px;
	}

	.captchaImgBox {
		width: 750rpx;
		display: flex;
		flex-direction: row;
		justify-content: flex-start;
	}

	.captchaImg {
		width: 220rpx;
		height: 80rpx;
		border: #007AFF solid 1px;
	}
</style>

四.token校验

一个校验客户端用自带的***uniIdToken***发起请求(uniCloud.callFunction),获得用户的uid、token、token的过期时间、角色、权限、用户信息(uni-id-users全部字段)的API。

这是非常高频且重要的API通常用于换取操作当前云函数的用户***uid***。

思考
如果你并没有服务端开发经验,可能会想:为什么需要通过token去换取用户Id,而不是让客户端直接传递用户Id更方便?

token===>>>uid

// 云函数list-news代码
const uniID = require('uni-id')
exports.main = async function(event,context) {
    const payload = await uniID.checkToken(event.uniIdToken)
  const {
    code,
    token,
    tokenExpired
  } = payload
  if(code) { // code不为0代表token校验未通过
    return payload
  }
  // 其他业务代码
  return {
    token,
    tokenExpired
  }
}

五.更新用户信息

// 云函数代码
const uniID = require('uni-id')
exports.main = async function(event,context) {
  payload = await uniID.checkToken(event.uniIdToken)
  if (payload.code) {
      return payload
  }
    const res = await uniID.updateUser({
    uid: payload.uid,
    nickname: 'user nickname'
  })
    return res
}

六.获取用户信息

// 云函数代码
const uniID = require('uni-id')
exports.main = async function(event,context) {
  payload = await uniID.checkToken(event.uniIdToken)
  if (payload.code) {
      return payload
  }
    const res = await uniID.getUserInfo({
    uid: payload.uid,
    field: ['mobile']
  })
    return res
}

在这里插入图片描述

//根据token获取用户信息
// 云函数代码
const uniID = require('uni-id')
exports.main = async function(event,context) {
    const res = await uniID.getUserInfoByToken(event.uniIdToken)
    return res
  // res = {
  //   uid: 'xxx',
  //   role: [],
  //   permission: []
  // }
}

在这里插入图片描述

七.过滤拦截用户请求

// 拦截用户某些请求
// 构建放行数组
// 拦截未登录以及登录失效
// 过滤非法请求
'use strict';
const uniIDs = require('uni-id')
exports.main = async (event, context) => {
	let res = {}; //响应
	let params = event.params ?event.params:{}; //接收请求数据
	const release = ['login', 'register', 'logout'];// 构建放行数组
	if (release.indexOf(event.action) == -1) {
			if (!event.uniIdToken) {
				res = {
					code: 403,
					message: "未携带token"
				}
				return res;// 拦截未登录以及登录失效
			} else {
				let payload = await uniID.checkToken(event.uniIdToken, {});
				if (payload.code === 0) {
					params.uid = payload.uid;
				} else {
					res = payload;
					return res;// 拦截未登录以及登录失效
				}
			}
	}
	switch (event.action) {
		...进行对应操作
		default: {
			res = {
				code: 402,
				message: "请求非法"// 过滤非法请求
			}
			break;
		}
	}	

	//返回数据给客户端
	return res;
};



八.微信登录

在这里插入图片描述

注意
0.HBuilder X设置菜单中配置微信开发者工具路径
1.微信开发者工具中,设置—安全设置—开启服务端口
2.需要在uni-id的config.json内app-plus对应的微信登录信息内配置appid和appsecret
3.manifest.json中配置微信appid
4.登录成功之后会返回token、tokenExpired,在获取token之后应进行持久化存储

uni.setStorageSync('uni_id_token', res.result.token)
uni.setStorageSync('uni_id_token_expired', res.result.tokenExpired)

5.打包并使用自定义基座(注意一定要在manifest.json填写微信appid后再制作自定义基座)

APP微信登录详细流程
===>uni.login
===>code
===>调用云函数uniID.loginByWeixin({code})
===>token
===>本地保存token
===>uni.getUserInfo()

//云函数wxLogin
'use strict';
const uniID = require("uni-id")
exports.main = async (event, context) => {
	return await uniID.loginByWeixin({
		code: event.code
	})
};

//本地index.vue
<template>
	<view class="content">
		<image class="logo" :src="userInfo.avatarUrl"></image>
		<view class="text-area">
			<text class="title">{{userInfo.nickName}}</text>
		</view>
		<button type="default" @click="login()">Login</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				userInfo: {}
			}
		},
		onLoad() {

		},
		methods: {
			getWXcode() {
				return new Promise((resolve, reject) => {
					uni.login({
						provider: "weixin",
						success: (e) => {
							resolve(e.code)
						},
						fail: () => {
							reject(new Error("微信登录失败"))
						}
					})
				})
			},
			login() {
				this.getWXcode().then(code => {
					console.log("code:" + code);
					uniCloud.callFunction({
						name: "wxLogin",
						data: {
							code
						}
					}).then(res => {
						console.log(res.result.code === 0 ? "微信登录成功" : "微信登录失败");
						if (res.result.code === 0) {
							uni.setStorageSync('uni_id_token', res.result.token)
							uni.setStorageSync('uni_id_token_expired', res.result.tokenExpired)
							let {
								openid,
							} = res.result
							console.log("openid:" + openid);
							return new Promise((resolve, reject) => {
								uni.getUserInfo({
									provider: "weixin",
									success: (e) => {
										resolve(e)
									},
									fail: () => {
										reject(new Error("getUserInfo失败"))
									}
								})
							})
						} else {
							return new Error("微信登录失败")
						}
					}).then(e => {
						let {
							userInfo
						} = e;
						this.userInfo = userInfo
						console.log(userInfo);
						const version=getApp().globalData.version
						console.log(version);
					}).catch(err => console.log(err))
				})
			}
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
如果你使用了uni-id插件来实现登录功能,可以按照以下步骤来实现TabBar登录拦截: 1. 在App.vue中引入uni-id插件,并初始化uni-id实例: ```vue <script> import uniID from 'uni-id' export default { async onLaunch() { // 初始化uni-id实例 uniID.init({ // 这里填写你的uni-id配置信息,如api地址、公共请求头等 }) // 判断用户登录状态,此处使用uni-id提供的登录状态判断方法 const res = await uniID.checkToken() if (res.code !== 0) { // 未登录,跳转到登录页面 uni.redirectTo({ url: '/pages/login/login' }) } } } </script> ``` 2. 在每个TabBar页面的onLoad生命周期函数中,判断用户是否已经登录: ```vue <script> export default { onLoad() { // 判断用户登录状态,使用uni-id提供的登录状态判断方法 uniID.checkToken().then(res => { if (res.code !== 0) { // 未登录,跳转到登录页面 uni.redirectTo({ url: '/pages/login/login' }) } }) } } </script> ``` 3. 在登录页面的处理逻辑中,使用uni-id提供的登录方法完成登录操作: ```vue <script> import uniID from 'uni-id' export default { methods: { login() { // 调用uni-id的登录方法进行登录操作 uniID.login({ // 这里填写你的登录参数,比如用户名、密码等 }).then(res => { if (res.code === 0) { // 登录成功,跳转回之前点击的TabBar页面 uni.navigateBack() } else { // 登录失败,处理错误逻辑 } }) } } } </script> ``` 以上代码示例基于uni-id插件来实现登录功能,具体的实现方式可能会根据你的项目需求和uni-id插件的使用方式有所不同。请根据实际情况进行相应的调整和修改。同时,请确保在登录成功后,将用户的登录信息保存到本地缓存中,以便下次启动应用时能够正确判断用户的登录状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光明有我16620122910

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值