您的位置 首页 java

Java应用一键接入验证码登录和小程序登录

最近实现了一个多端登录的 Spring Security 组件,用起来非常丝滑,开箱即用,可插拔,而且灵活性非常强。我觉得能满足大部分场景的需要。目前完成了手机号验证码和 微信 小程序两种自定义登录,加上默认的Form登录,一共三种,现在开源分享给大家,接下来简单介绍一下这个插件包。

DSL 配置风格

切入正题,先来看看配置:

      @ bean 
     Security Filter Chain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
         http. csrf ().disable()
                 .authorizeRequests()
                 .mvcMatchers("/foo/**")
                 .access("hasAuthority('ROLE_USER')").any Request ().authenticated()
                 .and()
                 // 默认form表单登录
                 .formLogin()
                 .and()
                 .apply(new LoginFilterSecurityConfigurer<>())
                 // 验证码登录
                 .captchaLogin(captchaLoginConfigurer ->
                                 // 验证码校验 1 在此处配置 优先级最高 2 注册为Spring Bean 可以免配置
                                 captchaLoginConfigurer.captchaService(this::verifyCaptchaMock)
                                         // 根据手机号查询用户UserDetials  1 在此处配置 优先级最高 2 注册为Spring Bean 可以免配置
                                         .captchaUserDetailsService(this::loadUserByPhoneMock)
                                         // 生成JWT 返回  1 在此处配置 优先级最高 2 注册为Spring Bean 可以免配置
                                         .jwtTokenGenerator(this::tokenResponseMock)
                         //todo 其它配置省略……
                 )
                 // 小程序登录 同时支持多个小程序
                 .miniAppLogin(miniAppLoginConfigurer -> miniAppLoginConfigurer
                                 // 实现小程序多租户
                                 // 根据请求携带的clientid 查询小程序的appid和secret 1 在此处配置 优先级最高 2 注册为Spring Bean 可以免配置
                                 .miniAppClientService(this::miniAppClientMock)
                                 // 小程序用户 自动注册和检索  1 在此处配置 优先级最高 2 注册为Spring Bean 可以免配置
                                 .miniAppUserDetailsService(new MiniAppUserDetailsServiceMock())
                                 // 小程序 sessionKey 缓存 过期时间应该小于微信官方文档的声明   1 在此处配置 优先级最高 2 注册为Spring Bean 可以免配置
                                 .miniAppSessionKeyCache(new MiniAppSessionKeyCacheMock())
                                 // 生成JWT 返回  1 在此处配置 优先级最高 2 注册为Spring Bean 可以免配置
                                 .jwtTokenGenerator(this::tokenResponseMock)
                         //todo 其它配置省略……
                 );
 
         return http.build();
     }  

这种风格完全贴合了 Spring Security DSL 配置风格,不仅仅高大上,而且可以按需配置。如果你没有验证码登录直接删掉 captchaLogin 方法;如果你没有微信小程序登录直接删掉 miniAppLogin 方法。甚至还可以对单种登录进行细粒度定制化, formLogin 有的功能基本验证码登录和微信小程序登录的都有。

为什么这么灵活?

这里抽象了一个登录配置类:

   public  abstract  class AbstractLoginFilterConfigurer<H  extends  HttpSecurityBuilder<H>, 
          C extends AbstractLoginFilterConfigurer<H, C, F>, 
          F extends AbstractAuthenticationProcessingFilter>
          extends AbstractHttpConfigurer<AbstractLoginFilterConfigurer<H, C, F>, H> {
              // 省略……
          }  

所有额外的登录渠道大都可以通过这个类来扩展,负责验证码登录的 CaptchaLoginFilterConfigurer 和微信小程序登录的 MiniAppLoginFilterConfigurer 都是该类实现的,基本上你看了源码也能照葫芦画瓢来一个。

另外上面这些配置项接口,都可以放在 Spring IoC 中,配置类能自动获取,不过优先级最高的还是通过上面代码中配置的具体实现,原理参见下面的的样例:

    @Override
      protected AuthenticationSuccessHandler defaultSuccessHandler(H http) {
          // 如果配置类没有配置 就尝试去Spring IoC中发现
          if (this.jwtTokenGenerator == null) {
               ApplicationContext  applicationContext = http.getSharedObject(ApplicationContext.class);
              jwtTokenGenerator = getBeanOrNull(applicationContext, JwtTokenGenerator.class);
          }
          Assert.notNull(jwtTokenGenerator, "jwtTokenGenerator is required");
          return new LoginAuthenticationSuccessHandler(jwtTokenGenerator);
      }
  
  
      public final <T> T getBeanOrNull(ApplicationContext applicationContext, Class<T> beanType) {
          String[] beanNames = applicationContext.getBeanNamesForType(beanType);
          if (beanNames.length == 1) {
              return applicationContext.getBean(beanNames[0], beanType);
          }
          return null;
      }  

使用方法

自行使用 Maven 命令 mvn install 到本地仓库,然后引入:

          <dependency>
             <groupId>cn.felord</groupId>
             <artifactId>spring-security-extension</artifactId>
             <version>1.0.0</version>
         </dependency>  

然后参考样例 sample 项目进行开发,登录方式有三种。

普通登录

  
 POST /login?username=user&password=12345 HTTP/1.1
 Host: localhost:8080  

验证码登录

需要先实现必须的配置接口

发送验证码后调用验证码登录接口:

  
 POST /login/captcha?phone=11111111111&captcha=123123 HTTP/1.1
 Host: localhost:8080  

小程序登录

需要先实现必须的配置接口

前端先调用微信授权登录接口获取 openid :

  
 POST /miniapp/preauth?clientId=wxxda23234&jsCode=051A23234ZHa1tZ5yj3AOlFr HTTP/1.1
 Host: localhost:8080  

响应:

  {
     "code": 200,
     "data": {
         " err code": null,
         "err msg ": null,
         "sessionKey": null,
         "openid": "oWmZj5QBrZxxxxx8OUxRrZJi4",
         "unionid": "oS-dxxxxxx4w_x7dA-h9MIuA"
     },
     "msg": "",
     "identifier": true
 }  

然后调用小程序登录接口:

  POST /login/miniapp HTTP/1.1
 Host: localhost:8080
 Content-Type: application/json
 
 {
     "clientId": "wxd14qr6",
     "openId": "oWmZj5QBrZIBks0xx8OUxRrZJi4",
     "unionId": "oS-dK520tgW8xxxx7dA-h9MIuA",
     "iv":"LQUOt8BSTa7xxxpe1Q==",
     "encryptedData": "10hn3o4xxxxxrO/Ag5nRD3QkLSzduKnWuzN9B/H4Y0G5mDPR8siA7T8yaaqZsrMycLAoe2qrd1J75yYetYuWifiq3jUrcceRZHVxxl9LnQdW8f5+pMTnQtCYiMJ7Jm9paCw2Bh+5Lowkyqkx1q0fALvCQ9LXPPLAbLOB9CavRfKoenAmyyHQjZ/6lz0njzA=="
 }
   

获取方式

代码已经托管到 Gitee

文章来源:智云一二三科技

文章标题:Java应用一键接入验证码登录和小程序登录

文章地址:https://www.zhihuclub.com/180766.shtml

关于作者: 智云科技

热门文章

发表回复

您的电子邮箱地址不会被公开。

1条评论

  1. Tetradox and Tetradox CAP are indicated for treatment of the following sexually transmitted infections American Association for Cancer Research AACR; 2022; 82 P4 11 33 P4 11 33 10

网站地图