公众号怎么登录的,公众号的账号怎么登录

首页 > 经验 > 作者:YD1662024-04-02 16:13:13

日常开发中,相信不管做 C 端还是 B 端业务的同学都会遇到微信相关的业务,比如微信登录、微信支付、公众号扫码关注等场景。

最近博主在做公众号扫码关注自动登录这一块的业务,因此总结绘制了一张「公众号扫码关注绑定手机号自动登录」流程图分享给大家。

公众号怎么登录的,公众号的账号怎么登录(1)

扫码关注绑定手机自动登录

推荐博主开源的 H5 商城项目「waynboot-mall」,这是一套全部开源的微商城项目,包含三个项目:运营后台、H5 商城前台和服务端接口。实现了商城所需的首页展示、商品分类、商品详情、商品 sku、分词搜索、购物车、结算下单、支付宝/微信支付、收单评论以及完善的后台管理等一系列功能。 技术上基于最新得 Springboot3.0、jdk17,整合了 MySql、Redis、RabbitMQ、ElasticSearch 等常用中间件。分模块设计、简洁易维护,欢迎大家点个 star、关注博主。

github 地址:https://github.com/wayn111/waynboot-mall

1. 准备工作

想要达到用户扫描二维码打开微信公众号主页并且关注后自动登录,目前只能通过接入公众号的服务器配置来完成,下面介绍下前置准备。

  1. 注册微信公众平台服务号(注意:不要注册成订阅号!因为「生成带参数的二维码」这个接口只有服务号能调用)
  2. 开通微信认证(注意:微信认证每年需要交 300 块钱),如下图展示即可认为前两步配置已完成。

公众号怎么登录的,公众号的账号怎么登录(2)

配置已完成

  1. 进入公众号后管【设置与开发】-【基本设置】,点击「开发者密码(AppSecret)启用」,拿到 appId、secret,
  2. 部署服务端代码(需公网,因为第五步的服务器地址需要公网才能验证通过)

公众号怎么登录的,公众号的账号怎么登录(3)

weixin-java-mp-demo使用步骤

  1. 进入公众号后管【设置与开发】-【基本设置】,点击「服务器配置启用」后,填写相关的服务器地址、令牌、消息加解密密钥、消息加解密方式,点击提交等待服务器地址验证通过后即完成了所有前置准备工作。

ps: 公众号接入服务器配置后,以前设置的自动回复和自定义菜单就失效了,后续自定义菜单只能通过调用公众号的api接口来进行设置,自动回复则需要在 weixin-java-mp-demo 项目的事件接收代码中进行回复。

2. 扫码关注自动流程

现在我们基于公众号内提供的 api 来完成扫码关注自动登录的操作,流程如下,

2.1 客户端流程
  1. 用户打开网页、TV 端时请求服务端接口获取公众号二维码以及用户标识。
  2. 根据用户标识轮询用户扫码状态接口,获取用户是否注册信息。
  3. 用户扫码后如果是已注册就根据轮询接口返回的 token 进行登录。
  4. 用户扫码后如果是未注册就弹出绑定手机号弹窗,当用户绑定成功根据绑定接口返回的 token 进行登录。
2.2 服务端流程

服务端需要提供三个接口以及监听扫码事件来获取用户 openId 并以此判断该扫码用户是否注册。

  1. 生成带参数的二维码以及用户标识接口,生成带参数的二维码主要根据公众号提供的接口文档中「生成带参数的二维码」这个接口,以此当用户扫码后点击关注,服务端便可以接收到用户的「关注」事件。如果是已关注用户扫码,服务端就会接收到「扫码」事件,下面是生成参数二维码后的扫码事件相关说明。

公众号怎么登录的,公众号的账号怎么登录(4)

扫码事件相关说明

  1. 用户扫码状态轮询接口,轮询接口需要返回三个基本状态。状态一继续轮询,状态二未注册提示绑定手机,状态三已注册就返回 token 进行登录,是否注册的判断需要在接收到「关注」「扫码」事件时根据 openId 去数据库中查询用户的注册状态。
  2. 用户扫码关注后,服务端接收到相关事件,根据 openId 判断用户是否已注册,已注册就将轮询接口设置为已注册,并生成用户token。未注册就将轮询接口设置为未注册,提示绑定手机。
  3. 绑定手机号接口,到了绑定手机号接口就相对独立一些,不在依赖公众号相关接口以及事件通知,绑定成功返回用户登录 token 即可。
2.3 用户扫码流程

用户扫码流程只有用户扫码的动作。

  1. 扫码后未关注时,只有用户点击关注按钮,服务端就会收到「关注」事件。
  2. 扫码后已关注,服务端就会收到「扫码」事件。
3. 代码示例3.1 生成带参数二维码

@PostMapping("userQrcodeCreate") private Result<WeixinQrcodeResponseVO> userQrcodeCreate(@RequestBody @Validated WeixinMPRequestVO req) { log.info("========================userQrcodeCreate begin, req:{}========================", req); WeixinQrcodeResponseVO weixinQrcodeResponseVO = new WeixinQrcodeResponseVO(); try { if (!this.wxMpService.switchover(properties.getCurAppid())) { throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", properties.getCurAppid())); } String sceneType = req.getSceneType(); String uuid = IdUtil.fastSimpleUUID(); // 临时ticket WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(sceneType WEIXIN_MP_SCENCE_SPLIT uuid, WEIXIN_MP_USER_STATUS.getExpireTime()); String showQrCodeUrl = wxMpService.getQrcodeService().qrCodePictureUrl(ticket.getTicket()); Response response = HttpToolUtil.getRequest(showQrCodeUrl); if (!response.isSuccessful()) { return ResultUtil.error(ErrorCode.WEIXIN_CREATE_QRCODE_ERROR); } try (InputStream inputStream = response.body().byteStream()) { String base64 = ImageUtil.imgToBase64(inputStream, "image/jpg"); weixinQrcodeResponseVO.setImgBase64str(base64); weixinQrcodeResponseVO.setUuid(uuid); // 设置开始轮询 redisUtil.set(WEIXIN_MP_USER_STATUS.getKey(uuid), UserSanLoopStatusEnum.LOOP.getType(), WEIXIN_MP_USER_STATUS.getExpireTime()); } } catch (Exception e) { log.error("创建场景二维码失败", e); return ResultUtil.error(ErrorCode.WEIXIN_CREATE_QRCODE_ERROR); } Result<WeixinQrcodeResponseVO> success = ResultUtil.success(weixinQrcodeResponseVO); log.info("userQrcodeCreate end, resp:{}", success); return success; } 3.2 扫码后轮询

// 轮询状态枚举 public enum UserSanLoopStatusEnum { /** * 已过期 */ EXPIRED(1), /** * 继续轮询 */ LOOP(2), /** * 已注册 */ REG(3), /** * 未注册 */ NOT_REG(4), ; } // 开始轮询 public WeixinUserStatusResponseVO userStatus(WeixinMPRequestVO req) { String uuid = req.getUuid(); String source = req.getSource(); String openId = (String) redisUtil.get(WEIXIN_MP_USER_OPENID.getKey(uuid)); WeixinUserStatusResponseVO weixinUserStatusResponseVO = new WeixinUserStatusResponseVO(); Object value = redisUtil.get(WEIXIN_MP_USER_STATUS.getKey(uuid)); if (value == null) { return weixinUserStatusResponseVO.setStatus(UserSanLoopStatusEnum.EXPIRED.getType()); } Integer status = (Integer) value; // 如果用户扫码是已注册,就直接根据openId获取用户token if (status.equals(UserSanLoopStatusEnum.REG.getType())) { String token = getToken(openId); weixinUserStatusResponseVO.setToken(token); } return weixinUserStatusResponseVO.setStatus(status); } 3.3 关注事件处理

@Component public class SubscribeHandler extends AbstractHandler { @Autowired private ScanScenesHandler scanScenesHandler; @Override public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService weixinService, WxSessionManager sessionManager) throws WxErrorException { String openId = wxMessage.getFromUser(); this.logger.info("根据openid判断用户是否已注册" ); WxMpXmlOutMessage responseResult = null; try { responseResult = scanScenesHandler.handleSpecial(wxMessage, userWxInfo); } catch (Exception e) { this.logger.error(e.getMessage(), e); } ... return null; } } 3.3 扫码事件处理

@Component public class ScanHandler extends AbstractHandler { @Autowired private ScanScenesHandler scanScenesHandler; @Autowired private WeixinMpMsgReplyService weixinMpMsgReplyService; @Override public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> map, WxMpService weixinService, WxSessionManager wxSessionManager) throws WxErrorException { String openId = wxMessage.getFromUser(); this.logger.info("根据openid判断用户是否已注册" ); WxMpXmlOutMessage responseResult = null; try { responseResult = scanScenesHandler.handleSpecial(wxMessage, userWxInfo); } catch (Exception e) { this.logger.error(e.getMessage(), e); } ... return null; } } 总结

自此,本文所讲述的「公众号扫码关注绑定手机号自动登录」流程就讲解完毕了。

关注博主每周分享技术干货、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.