文章导航
微信小程序生态1-初识小程序
微信小程序生态2-创建一个微信小程序
微信小程序生态3-微信小程序登录流程设计
微信小程序生态4-扫普通二维码进入小程序、打开短链接进入小程序
微信小程序生态5-微信公众号扫码登录PC端网页
微信小程序生态6-微信公众号授权登录(适用于H5小程序)
微信小程序生态7-微信公众号设置IP白名单
微信小程序生态8-基于weixin-java-mp实现微信公众号被动回复消息
微信小程序生态9-微信开放平台unionId机制介绍
微信小程序生态10-微信公众号token验证失败
微信小程序生态11-一个二维码同时支持微信、钉钉、支付宝扫码打开小程序
微信小程序生态12-微信小程序开发设置中服务器域名和业务域名
微信小程序生态13-微信公众号自定义菜单、个性化菜单配置
微信小程序生态14-下线已发布的小程序
微信小程序生态15- 批量提交微信小程序审核的一种方式
演示效果
一、准备材料
1、已认证的公众号(必须为服务号,订阅号没有该接口的权限)
2、一个网址,用于微信回调,推荐一个内网穿透的工具:内网穿透
3、Redis,用于存储token
4、一个SpringBoot项目
二、实现原理
1、使用微信公众号(服务号)的appId和appSecret生成一个token,这个token可以复用,但是有时效性
2、使用token当做参数调用微信api:qrcode/create创建一个二维码
3、使用微信扫码,用户订阅后,微信官方会回调我们的一个地址,将openId传过来
4、将openId保存下来,下次扫描时根据openId进行判断用户身份
三、注意点
1、只有服务号才有生成带参数的二维码接口权限
2、该接口每天100000次,适用于小规模用户登录
3、获取的AccessToken有时效性,可以利用redis进行保存
4、公众号开发有白名单限制,所以服务端在调用时需要配置白名单
四、实现步骤
公众号相关
1、登录公众号,获取appId和appKey
2、配置服务器回调地址
服务端相关
1、创建SpringBoot项目将复制下来的appId和appkey配置好,并加上一个redis
2、由于微信的回调值格式是XML格式,所以需要一个解析工具类
package com.zzj.qlogin.utils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* 微信返回值解码工具类
*/
public class XmlUtil {
/**
* 简单解析xml
* @param in
* @return
*/
public static Map<String,Object> parseXML(InputStream in){
Map<String,Object> map=new HashMap<>();
try {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(in);
Element root = document.getRootElement();
Iterator iterator = root.elementIterator();
while (iterator.hasNext()){
Element element = (Element) iterator.next();
map.put(element.getName(),element.getStringValue());
}
} catch (DocumentException e) {
e.printStackTrace();
}
return map;
}
}
3、回调接口,此处需要区分两个不同的事件:订阅和扫码,简单的处理逻辑如下
/**
* 接收微信推送事件
* @param request
* @return
*/
@PostMapping("/handleWxCheckSignature")
@ResponseBody
public String handleWxEvent(HttpServletRequest request){
try {
InputStream inputStream = request.getInputStream();
Map<String, Object> map = XmlUtil.parseXML(inputStream);
String userOpenId = (String) map.get("FromUserName");
String event = (String) map.get("Event");
if("subscribe".equals(event)){
// TODO:获取openid判断用户是否存在,不存在则获取新增用户,自己的业务
//自己生成的二维码不管是关注还是扫码都能取到ticket凭证
String ticket = (String) map.get("Ticket");
redisCacheManager.set(ticket,ticket,10*60);
logger.info("用户关注:{}",userOpenId);
}else if("SCAN".equals(event)){
//自己生成的二维码不管是关注还是扫码都能取到ticket凭证
String ticket = (String) map.get("Ticket");
redisCacheManager.set(ticket,ticket,10*60);
logger.info("用户扫码:{}",userOpenId);
}
logger.info("接收参数:{}",map);
} catch (IOException e) {
e.printStackTrace();
}
return "success";
}