• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

微信公众号二维码扫码登录SpringBoot Java实现

武飞扬头像
啥也不懂的派大星
帮助1

一、业务场景

用户扫描公众号的二维码,实现登录当前平台。

若未关注公众号,则关注后触发登录;若已关注,则直接登录。 

登录时通过union_id判断用户是否在系统注册,若未注册则跳转到注册页面或提示未注册。

二、微信公众号准备

注意,此功能使用的接口,需要公众号类型为服务号才支持!

开发阶段,可使用微信提供的公众号测试号联调,扫码登录即可。

学新通

公众号后台登录地址

 三、涉及到微信公众号的接口

  • 获取 Access token,这个是必备的接口,跟此功能无关
  • 生成带参数的二维码,这个是微信生成公众号二维码图片链接的接口
  • 接收事件推送,这个是每次用户扫码后微信通知我们服务的接口,会携带用户的union_id,open_id,订阅动作(首次订阅、已订阅、取消订阅),二维码的唯一参数(可生成二维码时自定义)

四、springboot项目中实现

1、添加微信依赖。

  1.  
    <dependency>
  2.  
    <groupId>com.github.binarywang</groupId>
  3.  
    <artifactId>weixin-java-mp</artifactId>
  4.  
    <version>3.4.0</version>
  5.  
    </dependency>

2、添加配置

  1.  
    wx:
  2.  
    open:
  3.  
    config:
  4.  
    appid: wxaf53b783b34xxxxx
  5.  
    secret: c637179625663cfe2462c73f42b0xxxx
  6.  
    token: b4a2ba6365f741e89ca7e42200cxxxxx

appid和secret获取位置:

学新通

 token位置(下面配置回调地址时配置):

学新通

添加配置类

  1.  
    import lombok.Data;
  2.  
    import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
  3.  
    import me.chanjar.weixin.mp.api.WxMpService;
  4.  
    import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
  5.  
    import org.springframework.beans.factory.annotation.Value;
  6.  
    import org.springframework.context.annotation.Bean;
  7.  
    import org.springframework.context.annotation.Configuration;
  8.  
     
  9.  
    @Configuration
  10.  
    @Data
  11.  
    public class WxOpenConfig {
  12.  
     
  13.  
    @Value("${wx.open.config.appid}")
  14.  
    private String appid;
  15.  
     
  16.  
    @Value("${wx.open.config.secret}")
  17.  
    private String secret;
  18.  
     
  19.  
    @Value("${wx.open.config.token}")
  20.  
    private String token;
  21.  
     
  22.  
    @Bean
  23.  
    public WxMpService wxMpService() {
  24.  
    WxMpService service = new WxMpServiceImpl();
  25.  
     
  26.  
    WxMpInMemoryConfigStorage configStorage = new WxMpInMemoryConfigStorage();
  27.  
    configStorage.setAppId(appid);
  28.  
    configStorage.setSecret(secret);
  29.  
    configStorage.setToken(token);
  30.  
     
  31.  
    service.setWxMpConfigStorage(configStorage);
  32.  
    return service;
  33.  
    }
  34.  
    }

3、添加回调地址。

提供一个GET请求的接口。

  1.  
    @Autowired
  2.  
    private WxMpService wxMpService;
  3.  
     
  4.  
    /**
  5.  
    * 校验微信token
  6.  
    */
  7.  
    @GetMapping("/callBack")
  8.  
    @ApiOperation(value = "校验微信token", hidden = true)
  9.  
    public String checkSignature(String signature, String timestamp, String nonce, String echostr) {
  10.  
    // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
  11.  
    log.info("校验微信token,start");
  12.  
    if (wxMpService.checkSignature(timestamp, nonce, signature)) {
  13.  
    return echostr;
  14.  
    }
  15.  
    return "";
  16.  
    }

添加配置(添加完保存会回调):

学新通

4、开发获取微信二维码的接口。

  1.  
    /**
  2.  
    * 获取微信公众号二维码链接
  3.  
    **/
  4.  
    @GetMapping("/getMpQrCode")
  5.  
    @ApiOperation(value = "获取公众号二维码图片", notes = "注意有效期和sceneId")
  6.  
    public HttpResult<WxMpQrVO> getMpQrCode() {
  7.  
    //sceneId 场景值 是我自定义的随机唯一字符串,登录使用,也可写死
  8.  
    String sceneId = RandomUtils.getRandomNumBeginOne(10);
  9.  
    WxMpQrCodeTicket wxMpQrCodeTicket;
  10.  
    try {
  11.  
    wxMpQrCodeTicket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(sceneId, 300);
  12.  
    //300为二维码有效期,单位秒
  13.  
    } catch (WxErrorException e) {
  14.  
    log.error("获取微信公众号二维码链接失败", e);
  15.  
    throw new BusinessException("获取微信公众号二维码链接失败");
  16.  
    }
  17.  
     
  18.  
    WxMpQrVO wxMpQrVO = new WxMpQrVO();
  19.  
    BeanUtil.copyProperties(wxMpQrCodeTicket, wxMpQrVO);
  20.  
    wxMpQrVO.setSceneId(sceneId);
  21.  
     
  22.  
    return HttpResult.success(wxMpQrVO);
  23.  
    }

VO的代码: 

  1.  
    import io.swagger.annotations.ApiModelProperty;
  2.  
    import lombok.Data;
  3.  
     
  4.  
    /**
  5.  
    * 获取公众号二维码地址
  6.  
    *
  7.  
    * @author zwb
  8.  
    * @version 1.0
  9.  
    * @date 2023-04-06 11:10
  10.  
    */
  11.  
    @Data
  12.  
    public class WxMpQrVO {
  13.  
     
  14.  
    @ApiModelProperty(value = "ticket", notes = "获取二维码地址:https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=返回的ticket")
  15.  
    protected String ticket;
  16.  
     
  17.  
    @ApiModelProperty(value = "有效期")
  18.  
    protected int expireSeconds;
  19.  
     
  20.  
    @ApiModelProperty(value = "url")
  21.  
    protected String url;
  22.  
     
  23.  
    @ApiModelProperty(value = "场景ID", notes = "通过sceneId轮询1s调用是否登录接口")
  24.  
    protected String sceneId;
  25.  
     
  26.  
    }

5、扫码回调代码开发。

提供一个与第3步相同域名的POST接口。

  1.  
    /**
  2.  
    * 接收推送的数据
  3.  
    */
  4.  
    @PostMapping("/callBack")
  5.  
    @ApiOperation(value = "接收推送的数据", hidden = true)
  6.  
    public String subscribeProcessor(HttpServletRequest request) {
  7.  
    log.info("接收关注微信动作推送处理");
  8.  
    try {
  9.  
    // 获得Document
  10.  
    SAXReader reader = new SAXReader();
  11.  
    Document doc = reader.read(request.getInputStream());
  12.  
    // 解析xml,得到根节点
  13.  
    Element root = doc.getRootElement();
  14.  
    //发送方帐号(一个OpenID)
  15.  
    String fromUserName = root.elementText("FromUserName");
  16.  
    //消息创建时间 (整型)
  17.  
    String createTime = root.elementText("CreateTime");
  18.  
    //消息类型,event
  19.  
    String msgType = root.elementText("MsgType");
  20.  
    //事件类型,subscribe(订阅)、unsubscribe(取消订阅),SCAN
  21.  
    String event = root.elementText("Event");
  22.  
    // 事件KEY值,qrscene_为前缀,后面为二维码的参数值
  23.  
    String eventKey = root.elementText("EventKey").replace("qrscene_", "");
  24.  
     
  25.  
    log.info("微信公众号接收信息:{},{},{},{},{},", fromUserName, createTime, msgType, event, eventKey);
  26.  
     
  27.  
    WxMpUser wxMpUser = wxMpService.getUserService().userInfo(fromUserName);
  28.  
    if (Objects.isNull(wxMpUser)) {
  29.  
    throw new Exception(StrUtil.format("获取用户信息为空,fromUserName={}", fromUserName));
  30.  
    }
  31.  
     
  32.  
    String openId = wxMpUser.getOpenId();
  33.  
    if ("subscribe".equals(event) || "SCAN".equals(event)) {
  34.  
    String unionId = wxMpUser.getUnionId();
  35.  
     
  36.  
    //TODO 关注公众号触发事件,编写对应的处理逻辑,比如判断是登录还是注册,前端轮询通过sencenId或者二维码ticket去查
  37.  
    log.info("关注公众号触发事件,event[{}],FromUserName[{}],unionId[{}]", event, fromUserName, unionId);
  38.  
     
  39.  
    } else if ("unsubscribe".equals(event)) {
  40.  
    // 取消关注公众号触发事件,编写对应的处理逻辑
  41.  
    log.info("取消关注公众号触发事件,event[{}],FromUserName[{}]", event, fromUserName);
  42.  
     
  43.  
    }
  44.  
    } catch (Exception e) {
  45.  
    log.error("接收关注微信动作推送处理失败", e);
  46.  
    }
  47.  
     
  48.  
    return "ok";
  49.  
    }

到此,核心的代码就结束了,欢迎感兴趣的小伙伴留言~

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgakicj
系列文章
更多 icon
同类精品
更多 icon
继续加载