本系列文章记录“智能提醒助理”wx公众号 建设历程,记录实践经验、巩固知识点、锻炼总结能力。
本文介绍,如何让用户进入公众号之后就锁定用户,使用既注册,进入既可使用功能,去掉繁琐的登录认证流程。
一、需求出发点
当用户进入公众号后 就可以识别到用户标识,进行静默注册,后续就可以对用户提供推送或唤醒功能,同时获取unionID 与小程序进行关联绑定。
二、实现路径分析
1、在公众号菜单或者 设置的欢迎消息中 放置URL链接,用户点击链接 授权获取code,回调服务端, 服务端通过code 获取accessToken、openid和unionid。
2、对接公众号的关注事件,通过关注事件可以直接拿到openid。
方案1:可以获取到用户的头像、昵称信息,只要在微信环境中就可以,不用关注公众号,意味着可以通过链接转发,H5等方式方分享到群、朋友圈等。
方案2:仅可以拿到openid,不能获取到头像,昵称,优势是 关注公众号 即可获取unionID 锁定用户。
三、最终方案
方案1+方案2 结合使用。
方案1 用户链接分享引流,获取更新头像和昵称。
方案2 用于公众号 关注即注册。
四、实施路径
方案1:用户链接分享引流,获取更新头像和昵称。
1、设置菜单,暴露URL链接
在公众号中配置菜单链接,或者回复消息中设置链接
URL 格式:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=公众号APPID&redirect_uri=服务端回调接口地址&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
举例:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx56521ff82d0dxxx&redirect_uri=https://youdomain.com/api/auth/mpLogin&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
2、设置回调处理,获取code换取openid
3、通过openid拉取用户昵称头像
注意:处理成功之后 需要重定向到一个页面,给用户一个反馈和引导。
服务端通过code 获取accessToken、openid和unionid
https://api.weixin.qq.com/sns/oauth2/access_token
再通过开放平台 使用openid拉取用户信息
https://api.weixin.qq.com/sns/userinfo?access_token=
@RequestMapping("mpLogin")
public String mpLogin(String code, String state, HttpServletResponse response) throws IOException {
log.info("获取微信响应的参数code:{},state:{}",code,state);
// 1、获取 登陆凭证code
if (StringUtils.isEmpty(code)) {
return "code获取失败!";
}
// 2、通过code 获取accessToken、openid和unionid
String resData = null;
try {
resData = wechatUtil.mpOauth2(code);
} catch (IOException e) {
log.error("mpOauth2",e);
return "获取openid失败!";
}
HashMap<String, String> sessionData = JsonUtil.toObj(resData, HashMap.class);
log.info("H5登陆sessionData:" + sessionData);
String mpOpenid = sessionData.get("openid");
String unionId = sessionData.get("unionid");
// 解析响应结果
if (null == sessionData || StringUtils.isEmpty(mpOpenid)) {
return "解析openid失败!";
}
// 3、拉取用户信息
JSONObject wxUser = wechatUtil.getMpUserInfo(sessionData.get("access_token"),mpOpenid);
String avatar = wxUser.getString("headimgurl");
String nickname = wxUser.getString("nickname");
String loginIp = IpUtils.getIpAddr(request);
// 静默注册
UserInfo userInfo = userInfoService.silenceRegister(unionId,loginIp,"",mpOpenid,avatar,nickname);
log.info("公众号方式登录-账号绑定,静默注册完成:{}",userInfo.getId());
// 绑定成功提示
// response.sendRedirect("https://mp.weixin.qq.com/s/IU1-K2sixLsjscWy1sM7yw");
// 使用微信头像和昵称成功提示
response.sendRedirect("https://mp.weixin.qq.com/s/zykJLau9cSC8uR3g7zJFlg");
return "";
}
方案2:公众号 关注即注册
1、对接公众号关注事件接口
2、监听事件获取openid 静默登录
/**
* 接受微信回调过来的事件<br/>
* <a href="https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html">官方文档</a><br/>
* 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。
* 假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。
*/
@PostMapping("/configAuth")
public String receiveEvent(@RequestBody String data) {
try {
log.info("1微信推送的事件xml数据:{}",data);
//1、xmltobean 获取消息对象
WechatReceiveMsg wechatReceive = (WechatReceiveMsg) XmlUtil.xmlStrToJavaBean(data, WechatReceiveMsg.class);
//2、获取消息类型,根据Event 获取事件类型 unsubscribe subscribe
String messageType = wechatReceive.getMsgType();
String eventType = wechatReceive.getEvent();
// 发送方帐号(用户open_id)
String mpOpenid = wechatReceive.getFromUserName();
// 服务号主体(app_id)gh_75bf3c1b76b2
String mpAppId = wechatReceive.getToUserName();
//判断消息类型是否是事件消息类型
if (messageType.equals(WxMsgTypeEnum.EVENT.getCode())) {
log.info("公众号====>{}事件消息",eventType);
if (eventType.equals(WxEventEnum.SUBSCRIBE.getCode())) {
log.info("公众号====>新用户关注");
//3-1、关注服务号事件:
// 根据openid 拉取用户信息 获取unionid
// https://api.weixin.qq.com/cgi-bin/user/info
String unionid = wechatUtil.getUnionID(mpOpenid);
// 静默注册
UserInfo userInfo = userInfoService.silenceRegister(unionid,"","",mpOpenid);
log.info("关注服务号事件,静默注册完成:{}",userInfo.getId());
// 关注服务号 返回首次关注 交互信息。
String reply_msg = paramDictService.getKey(CacheConstant.MP_FIRST_REPLY_MSG);
String firstReply = wechatUtil.replyMpTextEvent(mpAppId,mpOpenid, reply_msg);
log.info("用户首次关注回复内容:{}",firstReply);
return firstReply;
} else if (eventType.equals(WxEventEnum.UNSUBSCRIBE.getCode())) {
//3-2、取消关注服务号事件:根据openid 查找用户,清理掉openid字段
userInfoService.resetUserMpOpenId(mpOpenid);
log.info("公众号====>用户{}取消关注处理成功",mpOpenid);
} else {
// 3-3、其他事件
log.info("用户:{}发送了{}类型的事件:{}",mpOpenid,wechatReceive.getMsgType(),wechatReceive.getContent());
}
}
} catch (Exception e) {
log.error("微信推送的事件,处理异常",e);
}
return "";
}
五、总结
静默登录的好处,在于无感平滑使用,提升用户交互体验。
在不同的场景使用精细化的处理方式,给拓客增加更多的可能性。
欢迎大家来体验这款新上线的 智能提醒工具,感兴趣的朋友可在公众号 留言交流。