uniCloud 微信小程序登陆全流程demo

news2024/9/9 8:02:12

ps:

        博主一向不喜欢废话,直接说几个点,你悟了就直接去试,可以不用看完,还是得自己去试印象才深刻,博主写博文就怕自己以后忘记做个笔记顺便能帮一个是一个

        1、你要获取unionid 肯定得访问外网,uniCould的访问外网api是uniCloud.httpclient.request,用法可以点后面这个api->简介@intro | uni-app官网,然后对接的微信官方获取unionid 的是这个地址小程序登录 | 微信开放文档

        2、uniCloud.httpclient.request 是放云对象里面,到时候你在同步到云端到云对象就可以

        3、涉及signature对比验证(sha1加密算法)

        4、涉及AES算法(存云对象的cryptojs,放心,不是让你cnpm install,你顺便还知道下怎么把依赖存云对象里)

        5、写完这篇博文博主没了半条命,uniCloud资料本来就少,你们全看完的,给我去点赞!

        一、准备:       

        1、记下AppID(小程序ID)、AppSecret(小程序密钥),

                顺便配置下云开发的地址(博主是申请阿里云的云开发5块钱的商用版的 所以配置这个,你要是免费到地址,你要开你微信开发工具请求云对象到时候的请求地址是啥配置进来就可以)

        

        2、微信开放平台---》微信开放平台

        绑定你的小程序,unionid 获取这一步逃不掉,个人也可以注册微信开发平台!!!!!!,当然如果你是公司项目,比如公众号和小程序都要知道是不是同一个用户登录,就得用公司的账号认证去开通微信开放平台

         3、组件

      pages/user/user.vue (你随便放一个page的vue文件里就好,记得你页面要配置路由,要访问到了)

pages.json要配置这个   pages/user/user.vue

<template>
	<view>
		<button class="loginBtn" open-type="getUserInfo"  @getuserinfo="wxGetUserInfo">授权登陆</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		computed: {
			
		},
		mounted(){
			let m=this;
		},
		methods: {
			wxGetUserInfo() {
				let m = this;
				m.tologin("weixin");
			},
			tologin(provider) {
				let m=this;
			    uni.login({
			        provider: provider,
			        // #ifdef MP-ALIPAY
			        scopes: 'auth_user', //支付宝小程序需设置授权类型
			        // #endif
			        success: (res) => {
						m.loginVal=res;   
						m.getUserInfo((res1)=>{
							let params={
							  "code": m.loginVal.code,
							  "rawData": res1.rawData,
							  "nickName": res1.userInfo.nickName,
							  "gender":res1.userInfo.gender,
							  "avatarUrl": res1.userInfo.avatarUrl,
							  "signature":res1.signature,
							  "encryptedData": res1.encryptedData,
							  "iv": res1.iv,
							  "language": res1.userInfo.language,
							  "city":res1.userInfo.city,
							  "province": res1.userInfo.province,
							  "country": res1.userInfo.country,
							}
							m.apiJscode2session(params)
						})
			        },
			        fail: (err) => {
			        }
			    });
			},
			async apiJscode2session(params){
				const co1 = uniCloud.importObject("col");
				let res=await co1.wxjscode2session(params);
				debugger
			},
			getUserInfo(suc) {
				suc=suc||function(){}
				
				uni.getUserInfo({
					provider: "weixin",
					success: (result) => {
						suc(result);
					},
				})
				// uni.getUserInfo({
				// 	provider: "weixin",
				// 	success: (result) => {
				// 		suc(result);
				// 	},
				// 	fail: (error) => {
						
				// 	}
				// });
			},
		}
	}
</script>

<style>

</style>

co1.wxjscode2session的云对象目录结构如下图

 index.obj.js 代码

// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
module.exports = {
	_before: function () { // 通用预处理器

	},
	say(str){
		return{
			code:"200",
			data:str
		}
	},
	async wxjscode2session(params){
		let m=this;
		
		let url="https://api.weixin.qq.com/sns/jscode2session?appid=你的AppID(小程序ID)&secret=你的AppSecret(小程序密钥)&js_code="+params.code+"&grant_type=authorization_code"
		const res = await uniCloud.httpclient.request(url, {
		    method: 'GET',
		    dataType: 'json' // 此处指定为json表示将此请求的返回值解析为json
		  })
		  debugger
		// https://api.weixin.qq.com/sns/jscode2session
		
	},
	/**
	 * method1方法描述
	 * @param {string} param1 参数1描述
	 * @returns {object} 返回值描述
	 */
	/* 
	method1(param1) {
		// 参数校验,如无参数则不需要
		if (!param1) {
			return {
				errCode: 'PARAM_IS_NULL',
				errMsg: '参数不能为空'
			}
		}
		// 业务逻辑
		
		// 返回结果
		return {
			param1 //请根据实际需要返回值
		}
	}
	*/
}

package.json

{
  "name": "col",
  "dependencies": {},
  "extensions": {
    "uni-cloud-jql": {}
  }
}

对了这里要配置

 好了,记得改完保存代码

接下去运行到小程序的时候,uniCloud控制台 开启断点调试,你可以还是连接本地云函数,毕竟我们本地开发,到时候记得同步到云端就好

点登陆,代码都给你们了,在上面那

 点登陆,hBuilder X 会一闪一闪

unionid 就出来了,

        核验signature

        好,我们接下核验signature1,服务器通过前端给的rawData 加获取的session_key使用sha1加密,计算出signature1

        这部有必要,比对前端传的signature和自己算出来的signature1是否一致(防止数据不一致,有时候延迟啥的,怕你存错unionid给不痛用户)

       我之前线上项目有碰到  第一个用户请求完了,第二个用户一起请求,结果返回第二个用户的信息(其实这也是防止别人抓包,拦截你的请求和返回给你假的用户数据来注册你的小程序

        1/在 云对象  cloudfunctions/col/index.obj.js 就是我上面那个给出的代码的module.exports = { 上面放两个函数


function encodeUTF8(s) {
	var i, r = [],
		c, x;
	for (i = 0; i < s.length; i++)
		if ((c = s.charCodeAt(i)) < 0x80) r.push(c);
		else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F));
	else {
		if ((x = c ^ 0xD800) >> 10 == 0) //对四字节UTF-16转换为Unicode
			c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000,
			r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F));
		else r.push(0xE0 + (c >> 12 & 0xF));
		r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
	};
	return r;
}

function sha1(s) {
	let m1 = this;
	var data = new Uint8Array(encodeUTF8(s))
	var i, j, t;
	var l = ((data.length + 8) >>> 6 << 4) + 16,
		s = new Uint8Array(l << 2);
	s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer);
	for (t = new DataView(s.buffer), i = 0; i < l; i++) s[i] = t.getUint32(i << 2);
	s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8);
	s[l - 1] = data.length << 3;
	var w = [],
		f = [
			function() {
				return m[1] & m[2] | ~m[1] & m[3];
			},
			function() {
				return m[1] ^ m[2] ^ m[3];
			},
			function() {
				return m[1] & m[2] | m[1] & m[3] | m[2] & m[3];
			},
			function() {
				return m[1] ^ m[2] ^ m[3];
			}
		],
		rol = function(n, c) {
			return n << c | n >>> (32 - c);
		},
		k = [1518500249, 1859775393, -1894007588, -899497514],
		m = [1732584193, -271733879, null, null, -1009589776];
	m[2] = ~m[0], m[3] = ~m[1];
	for (i = 0; i < s.length; i += 16) {
		var o = m.slice(0);
		for (j = 0; j < 80; j++)
			w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1),
			t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0,
			m[1] = rol(m[1], 30), m.pop(), m.unshift(t);
		for (j = 0; j < 5; j++) m[j] = m[j] + o[j] | 0;
	};
	t = new DataView(new Uint32Array(m).buffer);
	for (var i = 0; i < 5; i++) m[i] = t.getUint32(i << 2);

	var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function(e) {
		return (e < 16 ? "0" : "") + e.toString(16);
	}).join("");

	return hex;
}
module.exports = {
	_before: function() { // 通用预处理器

	},
	say(str) {

我就贴出部分代码你知道放哪里就好

然后wxjscode2session做改动

async wxjscode2session(params) {
		
		let url="https://api.weixin.qq.com/sns/jscode2session?appid=你的AppID(小程序ID)&secret=你的AppSecret(小程序密钥)&js_code="+params.code+"&grant_type=authorization_code"
		const res = await uniCloud.httpclient.request(url, {
			method: 'GET',
			dataType: 'json' // 此处指定为json表示将此请求的返回值解析为json
		})
		
		let unionid=res.data.unionid;
		//服务器通过前端给的rawData 加获取的session_key使用sha1加密,计算出signature1
		let signature1 = sha1(params.rawData + res.data.session_key);
		//比对前端传的signature和自己算出来的signature1是否一致(防止数据不一致,有时候延迟啥的,怕你存错unionid给不同用户)
		if(params.signature==signature1){//
			return res;//这边你可以做存用户unionid的请求操作
		}else{
			return false;
		}
		
		 
		// https://api.weixin.qq.com/sns/jscode2session
	},

这一步你云函数调试下就摘掉对错了,这个叫sha1算法加密解密,我备注写的很详细了!!!!!!,参考了下面这篇文章步骤微信小程序登录 + 基于token的身份验证_每天开心成为别人的望尘莫及的博客-CSDN博客的流程步骤,我按着他的思路来实现的。

AES算法解密encryptedData

        好,接下去来用AES算法解密encryptedData里的敏感数据,

这里你注意去看看公告,如果你通过解密encryptedData是行不通的,你看看公告小程序用户头像昵称获取规则调整公告 | 微信开放社区

但是如果你的版本库低于2.27.1版本的访问,还是可以!!!!!!!!博主没试过,懒得试,们要的自己可以试下,当然,如果老板应要,你也是没办法不是,

在这里改的版本库!!!!

先让你们看看博主解密的结果博主2.30.0的版本库,这个是解密encryptedData之后的。

 

 哎,考虑到低于2.27.1的小伙伴,雪狼还是写下操作步骤吧

解密encryptedData(大于2.27.1的小伙伴就不用试了,没意义

用AES算法解密encryptedData里的敏感数据,

        首先就得下AES算法公式,所以你得下CryptoJS依赖,

        但是CryptoJS 在uniCloud里是没有utils这个目录放依赖的概念的,

        更不可能让你cnpm生成个本地node_modules,

咋整???

你有两个办法你去cnpm install crypto-js 可以!!!!,但是你得移动目录,到你的云对象里,怎么移动?看下图,看懂了吗。

 博主不是这么操作!!!,先是去下了个crypto-js依赖包,这里借鉴下面这个博主,贴个原文,表示尊重和感谢,使用CryptoJS解决微信小程序用户信息解密 - 蔡-Rd - 博客园

博主的做法,

        1、先下个cryptojs 点击下载

        2、在cloudfunctions下的col新建一个文件夹node_modules  上图那你也看的到博主的目录,就是把解压后的cryptojs-master 重命名成cryptojs

        3、新建个RdWXBizDataCrypt.js,上图那也有放的目录

       代码如下

/**
 * Created by rd on 2017/5/4.
 */
// 引入CryptoJS
var Crypto = require('cryptojs/cryptojs.js').Crypto;
function RdWXBizDataCrypt(appId, sessionKey) {
  this.appId = appId
  this.sessionKey = sessionKey
}
 
RdWXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
  // base64 decode :使用 CryptoJS 中 Crypto.util.base64ToBytes()进行 base64解码
  var encryptedData = Crypto.util.base64ToBytes(encryptedData)
  var key = Crypto.util.base64ToBytes(this.sessionKey);
  var iv = Crypto.util.base64ToBytes(iv);
 
  // 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充
  var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);
  
  try {
    // 解密
    var bytes = Crypto.AES.decrypt(encryptedData, key, {
        asBpytes:true,
        iv: iv,
        mode: mode
    });
    
    var decryptResult = JSON.parse(bytes);
    
  } catch (err) {
    console.log(err)
  }
 
  if (decryptResult.watermark.appid !== this.appId) {
    console.log(err)
  }
 
  return decryptResult
}
 
module.exports = RdWXBizDataCrypt

        然后index.obj.js文件改动部分

const WXBizDataCrypt = require('./RdWXBizDataCrypt.js');
module.exports = {
	_before: function() { // 通用预处理器

	},
	say(str) {
		return {
			code: "200",
			data: str
		}
	},
	async wxjscode2session(params) {
		let url="https://api.weixin.qq.com/sns/jscode2session?appid=你的AppID(小程序ID)&secret=你的AppSecret(小程序密钥)&js_code="+params.code+"&grant_type=authorization_code"
		const res = await uniCloud.httpclient.request(url, {
			method: 'GET',
			dataType: 'json' // 此处指定为json表示将此请求的返回值解析为json
		})
		
		let unionid=res.data.unionid;
		//服务器通过前端给的rawData 加获取的session_key使用sha1加密,计算出signature1
		let signature1 = sha1(params.rawData + res.data.session_key);
		//比对前端传的signature和自己算出来的signature1是否一致(防止数据不一致,有时候延迟啥的,怕你存错unionid给不痛用户)
		var pc = new WXBizDataCrypt(你的AppID(小程序ID), res.data.session_key)
		var data = pc.decryptData(params.encryptedData , params.iv)
		debugger
		if(params.signature==signature1){//
			return res;//这边你可以做存用户unionid的请求操作
		}else{
			return false;
		}
		
		 
		// https://api.weixin.qq.com/sns/jscode2session
	},

这句别漏掉  !!!   const WXBizDataCrypt = require('./RdWXBizDataCrypt.js');

这个debugger那边上面到   data 你云调试下,就是你要得东西了(大于2.27.1微信版本库的小伙伴就别再说怎么没有了,博主上面都说过了!!!)

低于2.27.1的小伙伴如果试有数据,回来评论区顺便跟博主说下

对了你试了可以记得云函数同步云端去!!!!!!!!

你都看到这里 了,继续看下面文字吧。

写这篇博文没了半条命,毕竟要搞定这个流程还是有点难度的,云开发你又得有vue经验、还得有后端像数据库,node的一些概念,基本就全栈了,好在博主之前有egg全栈基础,网上云开发资料又少,全得博主去拼来猜,来试,博主都35了,后面不一定有命来给你试这些东西,你们都自己学着猜下,学会长大吧,趁我现在脑子没坏,能帮你们几年看命了,你们有点良心,博主主页左边那个公众号能关注的关注个,公众号发个“谢谢”,博主到时候看到应该会很感动。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/183119.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++初阶】六、STL---string(总)|为什么学习string类|标准库中的string类|string 类常用接口

目录 一、为什么学习string类 1.1 C语言中的字符串 1.2 字符串在OJ面试中 二、标准库中的string类 2.1 string 介绍 2.2 编码格式 三、string 类常用接口 3.1 Member functions&#xff08;成员函数&#xff09; 3.1.1 构造函数&#xff08;Construct&#xff09; 3.…

C++11 并发指南七(C++11 内存模型一:介绍)

C11 并发指南七(C11 内存模型一&#xff1a;介绍) 文章目录C11 并发指南七(C11 内存模型一&#xff1a;介绍)第六章主要介绍了 C11 中的原子类型及其相关的API&#xff0c;原子类型的大多数 API 都需要程序员提供一个 std::memory_order&#xff08;可译为内存序&#xff0c;访…

面试第一次被问到SDK测试,当时就懵了

01、是什么 客户端SDK是为第三方开发者提供的软件开发工具包&#xff0c;包括SDK接口、开发文档和Demo示例等。SDK和应用之间是什么关系呢&#xff1f;以云信即时消息服务为例&#xff0c;如下图所示&#xff0c;应用客户端通过调用云信SDK接口&#xff0c;进行消息等数据查询…

[前端笔记——CSS] 14.图像、媒体和表单元素

[前端笔记——CSS] 14.图像、媒体和表单元素1.CSS调整大小2.图片、媒体和表单元素2.1替换元素2.2 form元素2.3 举个实例1.CSS调整大小 一个空的<div>是没有尺寸的。如果在 HTML 文件中添加一个空<div> 并给予其边框&#xff0c;则会在页面上看到一条线。 <div…

【软件安装】ubuntu安装nvidia驱动,解决闪屏问题

Official Drivers | NVIDIA nvidia驱动下载官网&#xff0c;登陆速度是有点慢的&#xff0c;需要耐心等待 我的电脑是笔记本&#xff0c;ubuntu18.04.6&#xff0c;NVIDIA GeForce RTX 3050 Laptop GPU 天时地利人和的情况下&#xff0c;按照下面这篇博文就可以顺利安装nvidi…

【存储】etcd的存储是如何实现的(2)

在上一篇中&#xff0c;介绍了etcd底层存储的内容&#xff0c;包括wal、raft.MemoryStorage以及backend。在介绍backend时提到了backend只是etcd kv存储的一部分&#xff0c;负责持久化存储&#xff0c;backend加内存化treeIndex才构成etcd完整的支持mvcc的kv存储。所以这篇就来…

红队大量资产指纹探测工具和摄像头漏-洞渗-透和利用工具

红队大量资产指纹探测工具和摄像头漏-洞渗-透和利用工具。 Finger定位于一款红队在大量的资产中存活探测与重点攻-击系统指纹探测工具。在面临大量资产时候Finger可以快速从中查找出重点攻-击系统协助我们快速展开渗-透。 实际效果 URL批量扫描效果如下: 调用api进行资产收集效…

第九层(6):STL之queue

文章目录前情回顾queue概念queue容器需要注意的地方queue类内的构造函数queue类内的赋值操作queue类内的插入操作queue类内的删除操作queue类内的访问queue类内的大小操作下一座石碑&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;一名大一的智能制造专业学生&…

设计模式第4式:观察者模式Spring事件监听机制

前言 观察者模式是一种非常重要的设计模式&#xff0c;在JDK和Spring源码中使用非常广泛&#xff0c;而且消息队列软件如kafka、rocketmq等也应用了观察者模式。那么我们就很有必要学习一下观察者模式了。 随后我们来看看大名鼎鼎的事件监听机制&#xff0c;它是基于观察者模…

直波导与微环的耦合——Lumerical仿真1

微环与直波导的耦合的Lumerical仿真的一个记录&#xff0c;包括仿真步骤和一些问题的探究&#xff0c;参考自https://www.bilibili.com/video/BV1tF411z714。 &#x1f381;附Lumerical仿真文件 Lumerical第一个仿真一、建立结构1、放置微环结构2、修改结构二、光源1、放置光源…

React是不是MVVM架构?

首先说结论&#xff1a;不是 一、MVVM Model-View-ViewModel&#xff1a;一句话概括MVVM&#xff0c;操作数据&#xff0c;就是操作视图&#xff0c;就是操作DOM。开发者只需要完成包含申明绑定的视图模板&#xff0c;编写ViewModel中业务数据变更逻辑&#xff0c;View层则完…

MySQL(六):redo日志——保证事务的持久性

目录一、redo日志的基本介绍1.1 什么是redo日志1.2 redo日志的格式1.3 redo日志的类型1.4 Mini-Transaction二、redo日志的写入过程2.1 redo log block2.2 redo日志缓冲区2.3 将redo日志写入log buffer2.3 redo日志刷新到磁盘2.5 redo日志文件组2.6 redo日志文件格式2.7 log se…

【MySQL进阶】MySQL触发器详解

序号系列文章7【MySQL基础】运算符及相关函数详解8【MySQL基础】MySQL多表操作详解9【MySQL进阶】MySQL事务详解10【MySQL进阶】MySQL视图详解文章目录前言1&#xff0c;触发器1.1&#xff0c;触发器概述1.2&#xff0c;触发器使用环境2&#xff0c;触发器基本操作2.1&#xff…

CentOS7 安装单机 Kafka

一、单机安装 1、上传压缩文件到服务器、解压 tar -zxvf kafka_2.13-3.3.2.tgz -C /usr/local #解压到 usr/local目录下 进入解压目录下 更名kafka mv kafka_2.13-3.3.2/ kafka-3.3.2 2、配置环境变量 vim /etc/profile export KAFKA_HOME/usr/local/kafka-3.3.2export PATH$PA…

MySQL学习记录(9)InnoDB存储引擎

文章目录6、InnoDB存储引擎6.1、逻辑存储结构6.2、架构6.2.1、概述6.2.2、内存结构6.2.3、磁盘结构6.2.4、后台线程6.3、事务原理6.3.1、事务基础6.3.2、redo log日志6.3.3、undo log日志6.4、MVCC6.4.1、基本概念6.4.2、记录中隐藏字段6.4.3、undo log日志6.4.4、readview6.4.…

【Pytorch项目实战】之图像分类与识别:手写数字识别(MNIST)、普适物体识别(CIFAR-10)

文章目录图像分类与识别&#xff08;一&#xff09;实战&#xff1a;基于CNN的手写数字识别&#xff08;数据集&#xff1a;MNIST&#xff09;&#xff08;二&#xff09;实战&#xff1a;基于CNN的图像分类&#xff08;数据集&#xff1a;CIFAR-10&#xff09;图像分类与识别 …

Lua 函数 - 可变参数

Lua 函数 - 可变参数 参考至菜鸟教程。 Lua函数可以接收可变数目的参数&#xff0c;和C语言类似&#xff0c;在函数参数列表中使用三点...表示函数有可变的参数。 function add(...) local s 0 for i, v in ipairs{...} do --> {...} 表示一个由所有变长参数构成的数…

模拟实现C库函数(2)

"烦恼无影踪,丢宇宙~"上一篇的模拟实现了好几个库函数,strlen\strcpy\memcpy\memmove,那么这一篇又会增加几个常用C库函数的模拟实现 memset\itoa\atoi。一、memsetmemset - fill memory with a constant byte#include <string.h>void *memset(void *s, int c,…

机器自动翻译古文拼音 - 十大宋词 - 江城子·乙卯正月二十日夜记梦 苏轼

江城子乙卯正月二十日夜记梦 宋苏轼 十年生死两茫茫&#xff0c;不思量&#xff0c;自难忘。 千里孤坟&#xff0c;无处话凄凉。 纵使相逢应不识&#xff0c;尘满面&#xff0c;鬓如霜。 夜来幽梦忽还乡&#xff0c;小轩窗&#xff0c;正梳妆。 相顾无言&#xff0c;惟有泪千…

uniapp使用及踩坑项目记录

环境准备 下载 HBuilderX 使用命令行创建项目&#xff1a; 一些常识准备 响应式单位rpx 当设计稿宽度为750px的时&#xff0c;1rpx1px。 uniapp中vue文件style不用添加scoped 打包成h5端的时候自动添加上去&#xff0c;打包成 微信小程序端 不需要添加 scoped。 图片的…