首页>>后端>>java->搞定了!OAuth2使用验证码进行授权

搞定了!OAuth2使用验证码进行授权

时间:2023-12-06 本站 点击:0

现在验证码登录已经成为很多应用的主流登录方式,但是对于OAuth2授权来说,手机号验证码处理用户认证就非常繁琐,很多同学却不知道怎么接入。

认真研究胖哥Spring Security OAuth2专栏的都会知道一个事,OAuth2其实不管资源拥有者是如何认证的,只要资源拥有者在授权的环节中认证了就可以了,至于你是验证码、账密,甚至是什么指纹虹膜都无所谓。

Id Server实现

因此胖哥好像找到了将验证码接入Id Server的方式,前面胖哥开源了一个Spring Security的登录扩展包spring-security-login-extension,可以一键接入验证码登录和小程序登录,利用这个应该就能实现。因此我就改造了一番成功实现了这一功能。看下效果:

和之前相比,用户在授权过程中可以选择账密登录或者手机验证码登录。

这里你变通一下,是不是只要是验证码登录都可以兼容进去了呢?

大致原理

这里需要前后端协同实现。

后端

核心还是扩展包的用法,给HttpSecurity加入LoginFilterSecurityConfigurer配置,这里我改动了一下和原来包中的不太一样。这里登录成功后不能再返回JWT了,需要和账密登录保持一致,核心代码如下:

httpSecurity.apply(new LoginFilterSecurityConfigurer<>())     // 手机号验证码登录模拟         .captchaLogin(captchaLoginConfigurer ->    // 验证码校验 1 在此处配置 优先级最高 2 注册为Spring Bean 可以免配置                 captchaLoginConfigurer.captchaService(this::verifyCaptchaMock)   // 根据手机号查询用户UserDetials  1 在此处配置 优先级最高 2 注册为Spring Bean 可以免配置                          .captchaUserDetailsService(this::loadUserByPhoneMock)                          // 两个登录保持一致                          .successHandler(loginAuthenticationSuccessHandler)                          // 两个登录保持一致                          .failureHandler(authenticationFailureHandler);

其中loadUserByPhoneMock是模拟CaptchaUserDetailsService接口,根据手机号加载UserDetails:

private UserDetails loadUserByPhoneMock(String phone) throws UsernameNotFoundException {    return  // 用户名          User.withUsername(phone)            // 密码              .password("password")              .passwordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()::encode)              .roles("user", "mobile")              .build();        }

verifyCaptchaMock是验证码校验逻辑接口CaptchaService的模拟,这里写死为1234,实际开发中应该用缓存实现,从发码接口中存入缓存,在CaptchaService中调用缓存接口取出验证码进行校验:

private boolean verifyCaptchaMock(String phone, String code) {    //todo 自己实现缓存校验逻辑            return code.equals("1234");}

验证码发送的接口自由实现,这里不需要去定义规范,记得接入缓存就行了。

前端

前端只需要接入一个可以切换登录方式的登录页就行了。然后把验证码登录接口和发送验证码接口配进去就行了,授权登录页面为oauth2_login.html,通过其控制器,胖哥甚至加了一个开关enableCaptchaLogin来决定是否使用验证码认证方式。

@GetMapping("/login")public String oauth2LoginPage(Model model,                         @CurrentSecurityContext(expression = "authentication")                          Authentication authentication,                         @Value("${spring.security.oauth2.server.login.captcha.enabled:true}")                                   boolean enableCaptchaLogin,                 @RequestAttribute(name = "org.springframework.security.web.csrf.CsrfToken", required = false)                                   CsrfToken csrfToken) {     if (!(authentication instanceof AnonymousAuthenticationToken)){         return "redirect:/";     }     if (csrfToken != null) {         model.addAttribute("_csrfToken", csrfToken);     }     SystemSettings systemSettings = new SystemSettings();     model.addAttribute("enableCaptchaLogin",enableCaptchaLogin);     model.addAttribute("systemSettings", systemSettings);     return "oauth2_login";}

前端和验证码相关的JS处理:

        if ([[${enableCaptchaLogin}]]){            form.on('submit(mobile-login)', function (data) {                let loader = layer.load();                let btn = button.load({elem: '.login'});                $.ajax({                    url: '/login/captcha',                    data: data.field,                    type: "post",                    dataType: 'json',                    success: function (result) {                        layer.close(loader);                        btn.stop(function () {                            if (result.code === 200) {                                popup.success(result.msg, function () {                                    location.href = result.data.targetUrl;                                })                            } else if (result.code === 401) {                                popup.failure(result.msg);                            }                        })                    }                });                return false;            });            $('#captcha-btn').click(function (){                //TODO 这里接入验证码接口                popup.success('验证码已发送');            })        }

关于Id Server

Id Server是一个基于Spring Authorization Server的开源的授权服务器,大大降低OAuth2授权服务器的学习使用难度,提供UI控制台,动态权限控制,方便OAuth2客户端管理,可以一键生成Spring Security配置,开箱即用,支持集成Spring Boot、Spring Cloud等java生态的框架,甚至支持其它语言,少量配置就可部署,代码开源,方便二次开发,支持OAuth2四种客户端认证方式和三种授权模式,支持账密认证和验证码认证。欢迎学习使用并参与代码贡献。

总结

OAuth2使用验证码进行授权已经实现了,适用于所有Id Server提供的DEMO。如果有兴趣可以从以下仓库地址获取最新的验证码授权代码,记得给个Star哦:

https://github.com/NotFound403/id-server

另外还有人问Id Server和胖哥Spring Security OAuth2专栏的关系,Id Server是一个开源项目,底层的逻辑支撑来自对Spring Authorization Server的分析,掌握专栏的知识可以帮助你对Id Server的自定义改造,Id Server目标是打造一个生产可用的OAuth2授权服务器,降低OAuth2的学习使用成本,希望大家多多支持。

关注公众号:Felordcn获取更多资讯

个人博客:https://felord.cn

原文:https://juejin.cn/post/7099761823456428045


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/java/15901.html