赞
踩
算是个系列内容吧,最终要实现的是将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)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。