spring boot项目实现 微信扫码登陆

扫码登录需要一个微信公众号,只有关注了这个公众号的微信,才有权限扫码登录。所以首先申请一个微信公众号。
1.公众号

- 打开下面网址申请一个测试公众号用作开发测试
  ```
  https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
扫码登录

申请一个公众号

扫码关注公众号

- 配置回调域名
  
  找到网页账号

点击修改,配置你的域名,如果没有自己的域名建议下载一个花生壳,花生壳6块钱能买一个https的域名内网穿透‘
2.编码

下面代码以spring boot为例,这里引入了一个集成好的依赖,如果想自己开发对应方法,请参考[微信开发文档](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html),很简单


- 引入pom依赖
  ```xml
  <!-- wx -->
  <dependency>
      <groupId>com.github.binarywang</groupId>
      <artifactId>weixin-java-mp</artifactId>
      <version>3.7.0</version>
  </dependency>
  
  <!-- tool -->
  <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>5.8.20</version>
  </dependency>
  
  <!-- zxing -->
  <dependency>
      <groupId>com.google.zxing</groupId>
      <artifactId>core</artifactId>
      <version>3.5.1</version>
  </dependency>
  ```


- yml配置文件中加入以下配置
  ```
  wx:
    #公众号的appID
    app-id: wxbe******d3b006f6
    #公众号的appsecret
    secret: f9ac33a******8aa2c17f3b70f921251
    #公众号中配置的域名
    domain: https://api.12121.com
    #接口回调地址
    redirect-url: /work/wx/user/info
  ```
- 编写配置类
  ```java
  @Data
  @Component
  @RefreshScope
  @ConfigurationProperties(prefix = "wx")
  public class WeChatProperty {
  
      private String appId;
  
      private String secret;
  
      private String domain;
  
      private String redirectUrl;
  
  }
  ```

- 注入Bean
  ```java
  @Configuration
  public class WeChatConfig {
  
      @Resource
      private WeChatProperty weChatProperty;
  
      @Bean
      public WxMpService wxMpService() {
          WxMpService wxMpService = new WxMpServiceImpl();
          wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
          return wxMpService;
      }
  
      @Bean
      public WxMpConfigStorage wxMpConfigStorage() {
          WxMpDefaultConfigImpl wxMpConfigStorage = new WxMpDefaultConfigImpl();
          wxMpConfigStorage.setAppId(weChatProperty.getAppId());
          wxMpConfigStorage.setSecret(weChatProperty.getSecret());
          return wxMpConfigStorage;
      }
  }
  ```

- service接口
  ```java
  public interface WeChatService {
  
      /**
       * 获取扫码登录二维码
       *
       * @param state state
       */
      void getQr(String state);
  
      /**
       * 获取扫码登录二维码
       *
       * @param state state
       * @return 二维码
       */
      BaseResult<?> getQrData(String state);
  
      /**
       * 获取用户信息
       *
       * @param code  code
       * @param state state
       * @return 用户信息
       */
      BaseResult<?> userInfo(String code, String state);
  }
  ```

- service接口实现类
  ```java
  @Slf4j
  @Service
  @RequiredArgsConstructor(onConstructor = @__({@Autowired}))
  public class WeChatServiceImpl implements WeChatService {
  
      private final WxMpService wxMpService;
  
      private final WeChatProperty weChatProperty;
  
      @Override
      public void getQr(String state) {
          try {
              ImgUtil.write(getQrImage(state), ImgUtil.IMAGE_TYPE_PNG, ServletUtil.getResponse().getOutputStream());
          } catch (Exception e) {
              log.info(ExceptionUtils.getStackTrace(e));
          }
      }
  
      @Override
      public BaseResult<?> getQrData(String state) {
          return ResultUtil.buildResultSuccess(ImgUtil.toBase64DataUri(getQrImage(state), ImgUtil.IMAGE_TYPE_PNG));
      }
  
      @Override
      public BaseResult<WxMpUser> userInfo(String code, String state) {
          try {
              WxMpOAuth2AccessToken token = getToken(code);
              WxMpUser userInfo = wxMpService.oauth2getUserInfo(token, null);
              return ResultUtil.buildResultSuccess(userInfo);
          } catch (WxErrorException e) {
              log.error(ExceptionUtils.getStackTrace(e));
          }
          return ResultUtil.buildResultError(ResponseCodeEnum.WX_GET_USER_INFO_ERROR);
      }
  
      /**
       * 获取token信息
       *
       * @param code code
       * @return token信息
       */
      private WxMpOAuth2AccessToken getToken(String code) {
          try {
              return wxMpService.oauth2getAccessToken(code);
          } catch (WxErrorException e) {
              log.error(ExceptionUtils.getStackTrace(e));
          }
          return null;
      }
  
      /**
       * 获取鉴权地址
       *
       * @param scope 鉴权类型
       * @param state state
       * @return 扫码鉴权地址
       */
      private String getRedirectUrl(String scope, String state) {
          return wxMpService.oauth2buildAuthorizationUrl(getCallbackUrl(), scope, state);
      }
  
      /**
       * 获取回调地址
       *
       * @return 回调地址
       */
      private String getCallbackUrl() {
          return weChatProperty.getDomain() + weChatProperty.getRedirectUrl();
      }
  
      /**
       * 获取验证二维码图片
       *
       * @param state state
       * @return 图片
       */
      private BufferedImage getQrImage(String state) {
          return QrCodeUtil.generate(getRedirectUrl(WxConsts.OAuth2Scope.SNSAPI_USERINFO, state),
                  QrConfig.create()
                          .setWidth(300)
                          .setHeight(300));
      }
  }
  ```

- 编写Controller
  ```java
  @Tag(name = "WX", description = "md相关接口")
  @RestController
  @RequestMapping("/wx")
  @RequiredArgsConstructor(onConstructor = @__({@Autowired}))
  public class WeChatController {
  
      private final WeChatService weChatService;
  
  
      @Operation(tags = "WX", summary = "获取验证图片", method = "/userInfo", description = "获取验证图片")
      @PassToken
      @GetMapping("/qr")
      public void getQr(@RequestParam("state") String state) {
          weChatService.getQr(state);
      }
  
      @Operation(tags = "WX", summary = "获取验证链接", method = "/userInfo", description = "获取验证链接")
      @PassToken
      @GetMapping("/qr/data")
      public BaseResult<?> getQrData(@RequestParam("state") String state) {
          return weChatService.getQrData(state);
      }
  
      @Operation(tags = "WX", summary = "获取用户详情接口", method = "/userInfo", description = "获取用户详情接口")
      @PassToken
      @GetMapping("/user/info")
      public BaseResult<?> userInfo(@RequestParam("code") String code, @RequestParam("state") String state) {
          return weChatService.userInfo(code, state);
      }
  }
  ```

### 3.使用

- 访问/wx/qr接口
  
  

- 微信扫码
  
  可以看到后端日志中已经获取到了用户的基本信息
  
 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值