-
我有一个微信小程序 “程序员实用资源”
-
我现在只想让我的微信群可以访问这个小程序的所有功能
-
所以我必须对我小程序的来源进行限制,让部分功能在正常访问的时候提示没有加群,不可访问,只有从群内点击进入小程序的时候才可以访问这部分功能
-
不用看,官网的微信小程序demo有bug,所以雪狼觉得有必要写篇博文,帮大家闭坑。
-
截止 2024年6月18日,你应该百度不到任何解决方案!因为问题,小程序限制微信群这个限制没什么人去搞。所以,收藏个,我怕你以后遇到了这个bug,没地方找到本文。
-
这个教程是我试通了我的小程序后回过来回忆写的,如果你搞不定,或者卡到哪个点,评论区留个言,雪狼有时间看到会回你。(37岁了,你问的时候最好雪狼还做前端。不做前端的话,就爱莫能助了。)
▍先看效果
直接点小程序进入是这样的
从群分享的卡片进入小程序是这样的
注意,你测试的时候,记得如果先直接点的小程序,在从群里点小程序,你要多清几次缓存,不然小程序被缓存住页面不会变
▍PART 教程
1、首先,限制群访问,肯定是要从小程序的访问来源入手
那么他首先要可!分!享!到群里,所有要在你要分享到群的那个test.vue页面(你自己建的测试页面)加下面这2个生命周期(雪狼是uniapp开发,原生的小伙伴自行去查分享群的方法)
onShareAppMessage(res) {//positionreturn {title: "test",path:url,//换成你自己页面的路由地址比如我是imageUrl:"/static/echarts.png"}
},//分享到朋友圈onShareTimeline(res) {let m=this;return {title: "test",type: 0,query: {},summary: "",imageUrl: "/static/logo.png"}},
2、别着急,假设你真从群里跳到了你自己的小程序的我假设是test.vue这个页面,你是要知道知道从!哪!里!跳过来的
所以我们在test.vue这个页面要加来源判断
onLoad(option) {let m=this;m.roldFun()
},
roldFun(){let m =this;var ly=uni.getLaunchOptionsSync()
console.log(ly)switch(ly.scene){case 1008://群聊会话中的小程序信息case 1044://群卡片case 1158://群工具case 1185://群公告case 1022://聊天置顶//m.quliao();//为了防止你复制完报错,我先注释掉,break;default://m.userRoldYZ();//break;}
},
附上getlaunchoptionssync的文档api大家自己可以前往查看https://uniapp.dcloud.net.cn/api/getLaunchOptionsSync.html#getlaunchoptionssync
下面是一些说明:方便你理解,你赶时间就直接跳过说明,直接跳到第3步骤
default 里雪狼是做了一个openid的验证,你们不用去管这个,其实就是被记录openid的用户可以不进过群聊可以查看所有数据
上面这部其实就是把群聊进入小程序的场景都放进去了case,我提醒下小伙伴,你其他场景可以在开发者工具里面找到对饮的code
好m.quliao() 里,就是你自己写在methods里的自己的方法,这里就看你的悟性了,我理下大概流程,
你可以新建一个test.vue页面,然后页面本来没东西,如果从群聊进入小程序会进quliao()的方法,你可以在<template> 里放一个{{ss}} data定义一个ss:"",然后进入quliao给他赋值 this.ss=1,这样就可以验证你的这个逻辑是不是对的了
关于限制制定哪些群聊去访问小程序才显示ss=1,你就要进行判断,
是的,后端要录入你 允许访问小程序的每个群聊的key了
雪狼试过,获取到的key不管用雪狼大号还是小号微信登录都是唯一的!!!!
3、test.vue通过getGroupEnterInfo获取某个群聊详情(前面说过了,不管通过哪个账号访问这个群聊,这个群聊key都是唯一的)
附上getGroupEnterInfo的文档api =》》https://developers.weixin.qq.com/miniprogram/dev/api/open-api/group/wx.getGroupEnterInfo.html
getGroupEnterInfo可以获取到encryptedData,iv,然后你是要配合uni.login获取到的code去解密encryptedData的
wx.getGroupEnterInfo({success(res){uni.login({provider: "weixin",// #ifdef MP-ALIPAYscopes: 'auth_user', //支付宝小程序需设置授权类型// #endifsuccess: (res1) => {//下面这个就是ajax请求后端的接口!!!你自己的请求,//要传的参数就是data里面encryptedData、iv、code//就是// uniCloud.callFunction({// name: 'user',// data: {// action:"pcDecryptData",// encryptedData:res.encryptedData,// iv:res.iv,// code:res1.code,// }// }).then((res2) => {// // 这里就是返回true或false了// })},fail: (err) => {}});}
})
这里提一嘴uni.login是不需要用户去主动按钮才能获取的!因为我们只是获取登录的code不是获取用户信息,
所以不需要像下面这样的按钮!!!!!
<button class="loginBtn" open-type="getUserInfo" @getuserinfo="wxGetUserInfo()">授权登陆</button>
我说的是不需要!!!!,你别直接就贴你代码里面去了!!!
来,接下去就是后端的活了!别赖给前端!!!只能从后端发起!!!!
雪狼用的是unicloud开发的,所有我贴下雪狼的代码,
async pcDecryptData(params){//这个是引入解密算法const WXBizDataCrypt = require('./RdWXBizDataCrypt.js');let m=this;//params 就是接收到前段发来的data的参数了,let url ="https://api.weixin.qq.com/sns/jscode2session?appid={你小程序的}appid&secret={你小程序的secret}&js_code=" +params.code + "&grant_type=authorization_code"//下面喝个是请求微信那边 获得session_key 来解密群const res = await uniCloud.httpclient.request(url, {method: 'GET',dataType: 'json' // 此处指定为json表示将此请求的返回值解析为json})var pc = new WXBizDataCrypt("{你的appid}",res.data.session_key)var data = pc.decryptData(params.encryptedData, params.iv) return data.opengid;},
你记得把{}这个尖括号给去掉!!!!!
雪狼是unicloud,如果你是php,java等你下官网的demo来看,https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
别急,你代码贴下去后是不能运行的,你先下下来,除了unicloud的小伙伴,其他后端小伙伴直接跳过下面这些看重点我画红线的地方开始看
如果你是unicloud,别问为什么先npm install cryptojs@2.5.3 ,别cnpm!!!!!!
重点,因为官方给的WXBizDataCrypt.js是不能用的
node语言的小伙伴用下面这个代码
你直接用雪狼改的这个RdWXBizDataCrypt.js (在说一遍,记得npm install cryptojs@2.5.3)
RdWXBizDataCrypt.js如下
/*** Created by rd on 2017/5/4.*/
// 引入CryptoJS
var Crypto = require('cryptojs/cryptojs.js').Crypto;
function RdWXBizDataCrypt(appId, sessionKey) {this.appId = appIdthis.sessionKey = sessionKey
}
RdWXBizDataCrypt.prototype.decryptData = function (encryptedData, iv,type) {// 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) {if(!type){console.log(err) }}
if (decryptResult.watermark&& decryptResult.watermark.appid !== this.appId) {console.log(err)}return decryptResult
}
module.exports = RdWXBizDataCrypt
非node语言的小伙伴,我提供思路
你最好在他的解密算法代码一个一个断点,decryptResult.watermark这段因为微信给到我们的数据结构已经变了,所以你会发现例如decryptResult.watermark.appid 这段时报错的。
所以你最好先判断decryptResult.watermark 再改decryptResult.watermark.appid
为什么呢?他原本算法解密后会返回群名称、群id、群appid、群简介那些,现在只返回群opengid,也就是群id唯一标识。
这时候你直接pc.decryptData(params.encryptedData, params.iv) 这一步就会报错,所以你得改WXBizDataCrypt.js的判断和返回
你可以看到我是直接返回return decryptResult 这个结果。可以了,
重点我都说了,这时候你前端uniapp请求后端unicloud就返回来opengid 就是群的唯一标识了,如果你要限制某个群可以访问 可以把opengid 存在后端服务器,然后前端传这些个参数给后端解密完顺便可以让后端去数据库判断是不是有这个群id,以此来判断是不是该返回给前端true.前端接收到true后,就可以把那些限制访问的内容v-if改成true,这样就实现了群聊访问小程序全部功能的功能
如果你卡到问题,可以在微信公众号搜:“程序员野区” 输入加群 找到我
▍PART 其他文章推荐
技术类:
-
常用的19个正则-表单验证
-
报错状态码 200 300 400 500
-
禁debugger调试网页,禁F12(完整教程)
-
用node开发微信群聊机器人第①章
-
我把微信群聊机器人项目开源
职场类:
-
我拿你当同事,你拿我当傻子(27)
-
程序员就不能不喝酒吗
-
贵人长啥样(24)
-
我对他那么好,为什么他还是要走(23)
-
第十八话:我为什么要走你不知道吗
-
程序员,爱情开始的地方(29)
关于雪狼:
===》开发者介绍《===
▍PART 公众号合集
#程序员干货 #前端回忆录