springboot整合微信(公众号)实现扫码登录(两种方式,两种实现)

简介: springboot整合微信(公众号)实现扫码登录(两种方式,两种实现)


首先说一下这个微信扫码登录它的方式有两种,一种是基于网页的redirect实现,一种是基于公众号推送消息实现,二者实现的效果是不一样的

基于公众号推送消息实现的扫码登录

贴一个官方文档

前期准备

  1. 需要有自己的域名(这里你可以使用内网穿透,会生成一个自己的域名,网上一大堆,自己奥利给吧)
  2. 需要申请微信认证(如果你是我这种情况,那么同是天涯沦落人,往下走)

  1. 这一步需要具备以上条件,否则没什么用(上面没有的就继续下)

如上图,获取到appid,appsecret(项目中会用到)之后,再将服务器配置修改并启用就可以了,

*服务器配置中的token到底怎么配置

微信官方文档公众号介入指南说明里面有一个PHP示例代码下载,其实这里不止PHP的

上面的是微信文档说明,下面一定要注意,很关键

  1. 首先说一下URL,这个URL是微信服务器需要使用get方式请求的你的路径,其次它是白名单的(当你配置拦截器或过滤器或AOP的时候)。这个get请求仅仅是验证token的。
  2. 其次是token,这里的token可以随意填写,但是你的程序中的token必须与这个保持一致(这里就是访问你上面URL的接口中的token)
  3. 代码实现如下:这里的代码实现在下面贴

使用测试号

配置的话和上面一样的操作

代码实现

maven坐标

<dependency>
  <groupId>com.github.binarywang</groupId>
  <artifactId>weixin-java-open</artifactId>
  <version>3.8.0</version>
</dependency>

配置类实现

import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author xiaobo
 * @date 2023/4/10
 */
@Configuration
public class WeChatCodeConfig {
    @Value("${wx.appid}")
    private String appId;
    @Value("${wx.appsecret}")
    private String appSecret;
    /**
     * 定义WxMpService bean
     */
    @Bean
    public WxMpService wxMpService() {
        WxMpService wxMpService = new WxMpServiceImpl();
        WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
        config.setAppId(appId);
        config.setSecret(appSecret);
        wxMpService.setWxMpConfigStorage(config);
        return wxMpService;
    }
}

上面的wx.appid,wx.appsecret是定义到配置文件中的,是在前期准备的第三点中获取到的

获取登录二维码

@PostMapping("/getLoginQrCode")
    @ResponseBody
    public RespResult getLoginQrCode() throws WxErrorException, UnsupportedEncodingException {
        // 设置场景id,登录的时候需要根据这个获取redis中存在的openid
        String sceneStr = IdUtil.getSnowflake().nextIdStr();
        WxMpQrCodeTicket wxMpQrCodeTicket = wxService.getQrcodeService().qrCodeCreateTmpTicket(sceneStr, 3600);
        // 这里获取到的是二维码,前端只需要用<img>标签中的src接收就可以展示
        String s = wxService.getQrcodeService().qrCodePictureUrl(wxMpQrCodeTicket.getTicket());
        return RespResult.success(s, sceneStr);
    }

上面的实现建议可以再做一步redis存一个有过期时间的key,防止后面一直轮询调用

前端轮询回调实现登录

@PostMapping("wechatOpenIdLogin")
    @ResponseBody
    public RespResult wechatOpenIdLogin(String sceneStr, HttpServletRequest request) {
      // 这里的sceneStr是上面接口返回的,这步操作是微信事件推送之后会存一个redis 
      Boolean exists = JedisUtil.exists(sceneStr);
        if (exists) {
            // TODO 业务操作,其中JedisUtil.getStr(sceneStr)能得到微信扫码用户的openid
            return weChatCodeService.wechatLogin(JedisUtil.getStr(sceneStr), request);
        } else {
            return RespResult.fail(sceneStr);
        }
    }

微信事件推送接口实现

@RequestMapping("/sign")
public void sign(HttpServletResponse response, HttpServletRequest request) throws Exception {
  String method = request.getMethod();
  // 微信加密签名
  String signature = request.getParameter("signature");
  // 随机字符串
  String echostr = request.getParameter("echostr");
  // 时间戳
  String timestamp = request.getParameter("timestamp");
  // 随机数
  String nonce = request.getParameter("nonce");
  // 签名验证是get请求
  if ("GET".equals(method)) {
    String[] str = {"123456token", timestamp, nonce};
    // 字典排序
    Arrays.sort(str);
    String bigStr = str[0] + str[1] + str[2];
    // SHA1加密
    String digest = sha1(bigStr);
    // 确认请求来至微信
    if (digest.equals(signature)) {
      response.getWriter().print(echostr);
    }
  } else {
    // 获取WxMpXmlMessage
    WxMpXmlMessage wxMpXmlMessage = WxMpXmlMessage.fromXml(request.getInputStream());
    // OpenId
    String fromUserName = wxMpXmlMessage.getFromUser();
    // 消息类型,event
    final String msgType = wxMpXmlMessage.getMsgType();
    // 事件类型
    final String event = wxMpXmlMessage.getEvent();
    String sceneStr = "";
    log.error("微信返回验签是:{},{},{}", msgType, event, fromUserName);
    if (WxConsts.XmlMsgType.EVENT.equals(msgType)) {
                if (event.equals(WxConsts.EventType.SUBSCRIBE)) {
                    if (ticket != null) {
                        sceneStr = wxMpXmlMessage.getEventKey().replace("qrscene_", "");
                    }
                }
                //注:事件类型为SCAN即已关注
                else if (event.equals(WxConsts.EventType.SCAN)) {
                    if (ticket != null) {
                        sceneStr = wxMpXmlMessage.getEventKey();
                    }
                }
                // 如果sceneStr不为空代表用户已经扫描并且关注了公众号
                if (CharSequenceUtil.isNotEmpty(sceneStr)) {
                    // 将微信公众号用户ID缓存到redis中,标记用户已经扫码完成,执行登录逻辑。
                    JedisUtil.setStr(sceneStr, fromUserName, OpenIdRedisExpireTime);
                }
            }
    response.getWriter().write("可以随便写");
  }
}

微信公众号接收事件推送

基于转发实现的扫码登录

这个和上面的不一样,这个用微信官方来说的话就是==网页授权获取用户基本信息==

前期准备

这里只需要获取到appid,appsecret,还有一个就是配置服务器域名如下图

代码实现

接口实现

这里需要用到上面公众号推送消息实现的->代码实现->(maven坐标,配置类实现)

/**
 * 获取微信扫码登录二维码
*/
@RequestMapping("/getLoginQrCode")
public RespResult getLoginQrCode() throws WxErrorException {
  // 重定向URl,这里必须配置公众号对应的域名
  String redirectUrl = "http://localhost:8080/login";
  // 这里只获取用户扫码地址
  String url = wxService.oauth2buildAuthorizationUrl(redirectUrl, WxConsts.OAuth2Scope.SNSAPI_BASE, null);
  return RespResult.success(url);
}
/**
 * 微信扫码登录
*/
@RequestMapping("wechatLogin")
public RespResult wechatLogin(@RequestParam("code") String code, HttpServletRequest request) {
  return weChatCodeService.wechatLogin(code, request);

⚠️: 注意,这里的url并不是一个二维码,而是一个地址,如果你在浏览器中打开的话,它会提示使用微信客户端打开,所以这个就注定了他并非根本意义上的扫码登录,它仅仅是微信扫码然后直接打开你跳转后的页面,也就是你上面定义的重定向URI,如果你的网站是手机端和PC端都兼容,那么可以直接PC出码,手机扫码直接登录。具体实现和上面的差不多,这里贴个图,针对上面的接口。

画的很丑,将就用吧

相关文章
|
自然语言处理 搜索推荐 小程序
微信公众号接口:解锁公众号开发的无限可能
微信公众号接口是微信官方提供的API,支持开发者通过编程与公众号交互,实现自动回复、消息管理、用户管理和数据分析等功能。本文深入探讨接口的定义、类型、优势及应用场景,如智能客服、内容分发、电商闭环等,并介绍开发流程和工具,帮助运营者提升用户体验和效率。未来,随着微信生态的发展,公众号接口将带来更多机遇,如小程序融合、AI应用等。
|
人工智能 前端开发 开发工具
9.2K Star!微信排版从未如此简单,这款开源神器让Markdown飞入公众号!
一款9.2K Star的开源神器,让微信公众号排版变得简单高效!支持Markdown语法,实时预览、多图床混搭、AI智能排版、自定义主题样式等功能一应俱全。通过沉浸式双栏编辑、七图床混合编排、AI写作助手和主题定制工坊等核心功能,彻底解放技术创作者的生产力。无论是技术博客迁移、多平台发布还是企业定制,都能满足需求。三步上手:在线体验、本地部署、公众号对接。项目地址:https://github.com/doocs/md
1849 4
|
小程序 JavaScript Java
基于SpringBoot的智慧停车场微信小程序源码分享
智慧停车场微信小程序主要包含管理端和小程序端。管理端包括停车场管理,公告信息管理,用户信息管理,预定信息管理,用户反馈管理等功能。小程序端包括登录注册,预约停车位,停车导航,停车缴费,用户信息,车辆信息,钱包充值,意见反馈等功能。
1029 5
基于SpringBoot的智慧停车场微信小程序源码分享
|
人工智能 自然语言处理
使用企业微信或公众号自动回复图片消息
AppFlow支持企业微信和公众号接收图片消息,并提供两种回复方式。方式一:直接回复图片消息,用户发送图片后立即收到回复,但无法继续追问。方式二:先保存图片,待用户发送文字后再一并处理并回复。配置步骤包括选择模板、配置鉴权信息、设置执行动作参数及发布连接流。详细操作可参考相关文档。
1783 1
使用企业微信或公众号自动回复图片消息
|
小程序 数据安全/隐私保护 开发者
【02】微信支付商户申请下户到配置完整流程-微信开放平台申请APP应用-微信商户支付绑定appid-公众号和小程序分别申请appid-申请+配置完整流程-优雅草卓伊凡
【02】微信支付商户申请下户到配置完整流程-微信开放平台申请APP应用-微信商户支付绑定appid-公众号和小程序分别申请appid-申请+配置完整流程-优雅草卓伊凡
1366 3
|
API
如何在公众号里制作微信报名表
微信万能表单不仅可以制作各种报名单,也可以用作问卷调查,商品发布,登记汇总等,可以根据自己需求,来添加组件,比如姓名、手机号、性别、报名的时间、报名的图片等,因为微信报名表涉及的用途比较广泛,所以很多商家在做微信公众号报名表的时候,针对性不会太强,没有什么局限性,应用还是起来比较方便的
925 12
|
移动开发 安全 JavaScript
SpringBoot接入微信JSSDK,看这篇妥妥的
这篇教程详细介绍了如何在Spring Boot项目中接入微信JSSDK,实现H5页面的自定义分享和调用相册选取图片等功能。文章首先通过对比理想与现实的分享效果,引出了接入微信JSSDK的必要性。接着,作者提供了GitHub和Gitee上的项目源码链接,并逐步讲解了整个接入过程的关键步骤,包括配置文件、主要类和方法的实现细节,以及必要的微信公众号设置。此外,还特别强调了几个常见问题及其解决方案,如域名绑定、IP白名单设置和签名验证等。最后,通过实际测试验证了功能的正确性。适合初学者快速上手微信JSSDK接入。
533 8
SpringBoot接入微信JSSDK,看这篇妥妥的
|
应用服务中间件 网络安全 Apache
Discuz! X3.5 开启ssl证书加密后微信、公众号无消息、支付宝通讯中断等
Discuz! X3.5 开启ssl证书加密后微信、公众号无消息、支付宝通讯中断等、支付宝支付实际支付成功,显示未支付等,都属于通讯中断,需要联系DZ官方付费修改程序,屏蔽防CC!
402 4
|
小程序 JavaScript Java
微信小程序+SpringBoot接入后台服务,接口数据来自后端
这篇文章介绍了如何将微信小程序与SpringBoot后端服务进行数据交互,包括后端接口的编写、小程序获取接口数据的方法,以及数据在小程序中的展示。同时,还涉及到了使用Vue搭建后台管理系统,方便数据的查看和管理。
微信小程序+SpringBoot接入后台服务,接口数据来自后端
|
小程序 搜索推荐 API
微信小程序:自定义关注公众号组件样式
尽管关注公众号组件的样式固定且不可修改,但产品经理的需求却需要个性化的定制。在这种情况下,我们需要寻找解决方案,以满足这些特殊需求,尽管这可能有点棘手。
1273 0
微信小程序:自定义关注公众号组件样式