• uniCloud开发公众号:三、生成带参数二维码


    算是个系列内容吧,最终要实现的是将uniCloud作为后端完成“扫码关注公众号后完成网站登录”
    将要涉及的内容可能包括:
    0.准备工作:各种配置、基础搭建
    1.接受、解析、组装xml消息
    2.请求access_token并缓存
    3.生成带参数二维码(本节)
    4.引入、封装redis缓存方法
    5.引入、配置、初始化unipush
    6.解析不同情况下用户扫码时推送的事件并完成登录

    系列内容全部基于uniCloud+vk-uniCloud(云函数路由)+uni-app
    编辑器HbuilderX最新版
    云空间为阿里云
    公众号为认证服务号

    一、编写云函数
    这个创建二维码的函数,笔者是直接放在了pub目录下/router/service/client/mp/pub/createQrCode.js,这样不需要鉴权即可直接生成,各位担心被滥用的话,也可以加一些简单的前后端验证,这里不再赘述。

    来看一下代码:

    'use strict';
    module.exports = {
    	/**
    	 * 生成二维吗
    	 * @url client/mp/pub/createQrCode 前端调用的url参数地址
    	 * data 请求参数
    	 */
    	main: async (event) => {
    		let { data = {}, userInfo, util, filterResponse, originalParam } = event;
    		let { customUtil, uniID, config, pubFun, vk, db, _ } = util;
    		let { uid } = data;
    		let res = { code: 0, msg: "" };
    		// 业务逻辑开始-----------------------------------------------------------
    
    		let clientAppid = data.client_appid; // 客户端平台appid
    		let pushClientid = data.push_clientid // unipush生成的客户端推送id
    		let sceneCode = vk.pubfn.random(6); // 随机生成的场景值
    		let currentTime = new Date().getTime(); // 当前时间戳
    
    		// 判断是否有未过期的二维码(ticket)
    		let oldTicketInfo = await vk.baseDao.findByWhereJson({
    			dbName: "wx-mp-cache",
    			whereJson: _.and([{
    					name: 'qrCodeTicket'
    				},
    				{
    					clientAppid: clientAppid
    				},
    				{
    					pushClientid: pushClientid
    				},
    				{
    					expire_time: _.gt(currentTime)
    				}
    			])
    		});
    
    		if (vk.pubfn.isNotNull(oldTicketInfo)) {
    			res.msg = 'get old';
    			res.data = oldTicketInfo.ticket;
    			return res;
    		}
    		
    		// 这里引用了第二节里封装的方法
    		let accessTokenInfo = await pubFun.getWxAccessToken();
    
    		// http请求方式: POST URL:
    		let url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=' + accessTokenInfo.token;
    		let response = await uniCloud.httpProxyForEip.postJson(
    			url, { "expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": { "scene": { "scene_id": sceneCode } } }
    		)
    		// 还是记得要parse
    		response = JSON.parse(response);
    		
    		// 换取二维码的ticket
    		let ticket = encodeURIComponent(response.body.ticket); 
    		
    		// 上边有请求交互,可能会浪费时间,不能直接用一开始的时间戳入库
    		currentTime = new Date().getTime(); // 当前时间戳
    
    		// 存入数据库
    		await vk.baseDao.add({
    			dbName: "wx-mp-cache",
    			dataJson: {
    				name: 'qrCodeTicket',
    				ticket: ticket,
    				clientAppid,
    				pushClientid,
    				expire_time: (parseInt(currentTime) + 60000)
    			}
    		});
    
    		// 缓存到redis
    		// 这里的方法下一节会讲到
    		if (vk.pubfn.isNotNull(ticket)) {
    			let keyName = 'qrscene_' + sceneCode; // redis的key
    			let redisJson = {
    				sceneCode,
    				clientAppid,
    				pushClientid,
    				expireTime: (parseInt(currentTime) + 60000)
    			}
    			// 这是一个封装好的redis方法
    			await pubFun.setRedisData(keyName, redisJson, 60);
    		}
    		
    		res.msg = 'create success';
    		res.data = ticket; // 把ticket返回给前端
    
    		// 业务逻辑结束-----------------------------------------------------------
    		return res;
    	}
    }
    
    '
    运行

    二、前端请求获取ticket
    一般是打开登录界面,就发起请求获取tikect,当然也可以是先用手机登录之类的,然后有个切换按钮来发起请求。

    // 创建并拉取公众号二维码
    vk.callFunction({
    	url: 'client/mp/pub/createQrCode',
    	title: '正在生成二维码', // loading的title
    	data: {
    		client_appid: uni.getSystemInfoSync().appId, // 原生方法获取发起请求的平台appid
    		push_clientid: vk.vuex.get('$user.push_clientid') // 这是在app.vue初始化unipush的时候生成并缓存到vuex的
    	}
    }).then(res => {
    	// 实际上拿到的是ticket,这里拼一下图片的url
    	this.qrCodeSrc = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' + res.data;
    	setTimeout(() => {
    		// 没登录的话60秒后提示过期
    		if (!vk.checkToken()) {
    			vk.toast('二维码已失效,点击重新获取');
    		}
    	}, 60000);
    });
    
    <view v-show="loginType == 'weixin'" class="weixin-qrcode" id="pologin">
    	<image class="qrCode" :src="qrCodeSrc" @click="getMpLogin">image>
    view>
    

    我这里这样弄完,就是从手机登录切换为微信登录时,发起请求拉取二维码;
    然后点击二维码时,可以再次拉取(有未过期的ticket时,拉取到的是未过期的ticket)。

  • 相关阅读:
    【音视频】H264编码基础
    python类对象
    基于A*、RBFS 和爬山算法求解 TSP问题(Matlab代码实现)
    STC32G 单片机EEPROM 操作实例
    ORB-SLAM2 ---- ORBextractor::operator()仿函数
    包含光栅的高NA显微系统
    Python ... takes 0 positional arguments but 1 was given
    5-爬虫-打码平台、打码平台自动登录打码平台、selenium爬取京东商品信息、scrapy介绍安装、scrapy目录结构
    【android 插件】alibaba的编码规范Java Coding Guidelines
    基于C#的房屋租赁管理系统设计与实现
  • 原文地址:https://blog.csdn.net/weixin_43945140/article/details/127113862