微信公众号平台Url Token EncodingAESKey 注意点
最近公司让我开发微信公众号平台扫码登录,同步用户信息于PC端,所做的过程当中遇到了一些坑,做完了就总结一下需要注意的点,如若大家开发过程中遇到同样的问题,可以借鉴!
第一:配置域名
作用:配置域名为了在微信的开发过程中,让微信服务器可以通过域名映射到调用你的服务器接口,进行后续的逻辑处理!
配置步骤:设置 --> 公众号设置 --> 功能设置 --> 网页授权设置 (设置你自己的域名即可)
注意:(1)根据微信官网描述,看到 MP_verify_HAlZDt72bkvxIrb6.txt 这个文件,需要下载下来放到你的根目录Webapp下,启动你的服务器。此时,微信服务器会自动的根据你所配置的域名 dcm.xxxxxx.cc/MP_verify_HAlZDt72bkvxIrb6.txt 访问这个文件,并成功读取到该文件中的内容就意味着配置成功!
(2)要是提示失败,有可能是你的服务器中配置了权限拦截,例如:登录权限
第二:配置微信服务器访问你接口的URL Token EncodingAESKey
作用:URL是开发者用来接收微信消息和事件的接口URL。Token可以由开发者任意填写,用作生成签名(该Token会配置在服务器中和接口URL中包含的Token进行比对,从而验证安全性)。EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。
配置步骤:开发 --> 基本设置 (填写URL Token EncodingAESKey)
注意(重中之重):Token EncodingAESKey 需要配置在你的服务器中 WxMpService 的 Config 中,此时还需要编写微信服务访问你接口的代码,返回微信服务器需要返回的结果才会提交成功(这一块的坑我遇到了好多:Token验证失效,URL超时之类,基本问题都是点击提交按钮,微信会自动访问你配置的接口不能返回微信所需要的结果)
例如:配置的域名为:dcm.xxxxxx.cc/mp/login/notify
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | @Controller @RequestMapping ( "/mp/login" ) public class ValidateWeiXin extends HttpServlet { private static final long serialVersionUID = 1L; private String TOKEN = "这里随便填入32位以内的数字英文,也就是token" ; @RequestMapping ( "/notify" ) protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType( "text/plain;charset=utf-8" ); // 微信加密签名 String signature = request.getParameter( "signature" ); // 随机字符串 String echostr = request.getParameter( "echostr" ); // 时间戳 String timestamp = request.getParameter( "timestamp" ); // 随机数 String nonce = request.getParameter( "nonce" ); String[] str = { TOKEN, timestamp, nonce }; Arrays.sort(str); // 字典序排序 String bigStr = str[ 0 ] + str[ 1 ] + str[ 2 ]; // SHA1加密,我这里用的是common-codec的jar包,你们也可以用java自带的消息消息摘要来写,只不过要多写几行代码,但结果都一样的 DigestUtils.sha1Hex(bigStr); String digest = DigestUtils.sha1Hex(bigStr); // 确认请求来至微信 if (digest.equals(signature)) { response.getWriter().print(echostr); } } } |
将这段代码写入你配置微信服务器访问的接口中,就可以提交成功了,后续需要重构这个接口中的代码,例如接收:微信扫码通知、关注通知、取消关注通知、接收发送消息等业务逻辑处理!
第三:微信扫码登录
(1)选用第三方SDK包:https://github.com/Wechat-Group/WxJava (个人认为这个SDK第三方Jar包涵盖了微信不同开发平台的所有功能,封装的很好,推荐使用)可以查看一下具体封装的特点和使用方式,可以提高开发效率!
(2)参考微信官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432
(3)需要详细阅读 【微信公众平台 --> 消息管理 --> 接收事件推送】 文档,借助第三方SDK工具包进行开发
(4)关注、取消公众号,微信会自动访问你配置的URL接口,根据接收的事件类型,处理不同的业务逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 用户未关注时,进行关注后的事件推送 <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime> 123456789 </CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> <EventKey><![CDATA[qrscene_123123]]></EventKey> <Ticket><![CDATA[TICKET]]></Ticket> </xml> 用户已关注时的事件推送(已经关注了,又扫码登录) <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime> 123456789 </CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[SCAN]]></Event> <EventKey><![CDATA[SCENE_VALUE]]></EventKey> <Ticket><![CDATA[TICKET]]></Ticket> </xml> |
自己编写的一段扫码通知、关注、取消关注的Controller代码,可以借鉴一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | @RequestMapping ( "/notify" ) public String wxnotify(HttpServletRequest request, HttpServletResponse response) { log.info( "【微信通知】wxnotify 接收到请求!" ); String message = "success" ; try { request.setCharacterEncoding( "UTF-8" ); response.setCharacterEncoding( "UTF-8" ); //把微信返回的xml信息转义成map Map<String, String> map = XmlUtil.xmlToMap(request); String fromUserName = map.get( "FromUserName" ); //消息来源用户标识 String toUserName = map.get( "ToUserName" ); //消息目的用户标识 String msgType = map.get( "MsgType" ); //消息类型 String eventType = map.get( "Event" ); String eventKey = map.get( "EventKey" ); log.info( "【微信通知】fromUserName = {}, toUserName = {}, msgType = {}, eventType = {}, eventKey={}" , fromUserName, toUserName, msgType, eventType, eventKey); if (WxConsts.XmlMsgType.EVENT.equals(msgType)) { //如果为事件类型 if (WxConsts.EventType.SCAN.equals(eventType)) { //扫码通知 if (StringUtils.isNotEmpty(eventKey)) { log.info( "【扫码通知】mid = {}" , eventKey); mpReceiveMessageService.scanQrCodeNotify(fromUserName, eventKey, redisTemplate); } } else if (WxConsts.EventType.SUBSCRIBE.equals(eventType)) { //关注通知 if (StringUtils.isNotEmpty(eventKey)) { String[] paramArray = eventKey.split( "_" ); String mid = paramArray[ 1 ]; log.info( "【关注通知】mid = {}" , mid); mpReceiveMessageService.subscribleNotify(fromUserName, mid, redisTemplate); message = MessageUtil.subscribeForText(toUserName, fromUserName); } } else if (WxConsts.EventType.UNSUBSCRIBE.equals(eventType)) { //取消关注通知 log.info( "【取消关注通知】" ); mpReceiveMessageService.unsubscribleNotify(fromUserName, redisTemplate); } } } catch (Exception e) { log.error( "【微信通知】异常, message = {}" , e.getMessage()); } return message; } |
如有问题,可以一起讨论,相互学习,我也是刚刚接触,需要后续继续努力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库