前言
最近因业务需要,需要给网站增加一个扫描公众号二维码登录网站的功能,通过扫码登录,一来用户登录网站不需再输入账号密码,提升了用户体验,二来也可以作为公众号吸粉的一个渠道。
开发准备
实现微信扫码登录需要一个认证的服务号,因为实现这个功能需要调用微信提供的接口生成一个带参的公众号二维码,而这个带参二维码生成接口只有认证的服务号才拥有这个接口的使用权,接口说明如图1-1所示。
图1-1 微信接口说明
流程说明
扫码登录的具体过程是这样的:用户打开登录页面时,前端在页面加载完成后随即请求后台生成带参公众号二维码,后台向微信发送请求生成二维码,微信将生成后的二维码、ticket(唯一值)等信息返回给开发者后台网页微信登陆,后台再将这些信息返回给前端,前端获取到这些信息后,首先将二维码显示在页面上,然后通过ticket作为id和后台建立websocket连接,并以此websocket连接来接收用户扫码事件的处理结果,当后台处理完成用户扫码事件后,通过websocket将处理结果发送至前端,前端根据处理结果进行相关业务操作,处理流程图如图1-2所示。
为什么使用websocket?
首先我们需要了解这样一个事实网页微信登陆,用户扫描二维码后,微信会将扫码事件推送到开发者服务器,而前端是无法知道后台对用户扫码的处理结果的,那么我们要怎么将处理结果通知前端呢?一种方式是轮询:前端不断向后台请求处理结果,这种方式明显不是很好,因而使用websocket刚好可以解决这个问题。
图1-2 微信扫码处理流程图
因相关业务代码较多,在此仅展示关键代码。
1.生成公众号带参二维码代码如代码清单1所示。
代码清单1 生成公众号带参二维码
//此处getToken方法内的参数需换成自己的服务号appid和secret
Token pubtoken = CommonUtil.getToken(WxConstant.FUWUHAO__APPID, WxConstant.FUWUHAO__SECRET);
JSONObject params = new JSONObject();
params.put("action_name", "QR_SCENE");
params.put("expire_seconds", 30000);
JSONObject action_info = new JSONObject();
JSONObject action_info_result = new JSONObject();
action_info_result.put("scene_id", 8);
action_info.put("scene", action_info_result);
params.put("action_info", action_info);
Map<String,Object> result = new HashMap();
try {
JSONObject res = JSON.parseObject(MyHttpRequestUtil.sendPost(CommonUtil.CONTAIN_PARAMS_QRCODE + pubtoken.getAccessToken(), params.toString()));
String ticket = URLEncoder.encode(res.getString("ticket"),"UTF-8");
String picUrl = CommonUtil.MP_QRCODE_PRE_URL + ticket;
log.info("二维码地址:picUrl:"+picUrl);
result.put("qrCodeUrl",picUrl);
result.put("ticket",ticket);
return ServerResponse.createBySuccess(result);
} catch (Exception e) {
e.printStackTrace();
}
2.用户扫码事件回调处理代码如代码清单2所示,需要说明的一点是,此回调函数即公众号配置的URL,如不了解如何配置的可参考我的另一篇文章:
Spring Boot微信公众号服务器配置案例。
代码清单2 用户扫描二维码回调事件处理
@ApiOperation("1.3:用户与公众号交互事件处理")
@RequestMapping("/getUserFocus")
public String handlePubFocus(HttpServletRequest request,HttpServletResponse response){
log.info("1.3:用户与公众号交互事件处理");
try{
Map requestMap = WxMessageUtil.parseXml(request);
Set keys = requestMap.keySet();
String messageType = requestMap.get("MsgType");
String eventType = requestMap.get("Event");
String openid = requestMap.get("FromUserName");
if(messageType.equals("event")){
//判断消息类型是否是事件消息类型
log.info("公众号====>事件消息");
log.info("openid:" + openid);
log.info("Event:" + eventType);
if(eventType.equals("subscribe")){
log.info("公众号====>新用户关注");
}else if(eventType.equals("unsubscribe")){
log.info("公众号====>用户取消关注");
}else if(eventType.equals("SCAN")){
log.info("公众号===>用户扫码动态二维码");
}else{
log.info("公众号===>其他");
}
}
娜娜项目网每日更新创业和副业项目
网址:nanaxm.cn 点击前往娜娜项目网
站 长 微 信: nanadh666
keys.forEach(item->{
String value = requestMap.get(item);
log.info(item + "===>" + value);
if(item.equals("Ticket")){
//当前用户进行了扫描动态二维码登录pc管理端操作
log.info("==>开始处理扫码登录");
log.info("当前用户openid:" + openid);
log.info("当前用户Ticket:" + value);
ldkjWxApiService.handleScanQrcode(openid,value);
}
});
}catch (Exception e){
e.printStackTrace();
}
return "";
}
运行结果:
1.登录首页生成二维码如图1-3所示。
娜娜项目网每日更新创业和副业项目
网址:nanaxm.cn 点击前往娜娜项目网
站 长 微 信: nanadh666