现在验证码登录已经成为很多应用的主流登录方式,但是对于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

搞定了!OAuth2使用验证码进行授权的更多相关文章

  1. 如何用python搞定验证码中的噪点

    背景:朋友在为"关山口男子职业技术学校"写一款校园应用,于是找MoonXue写一个学生选课系统的登录接口.为了搞定这个接口,不得不先搞定这个系统的验证码. 验证码大概是这个样子 看 ...

  2. 一张图搞定OAuth2.0 在Office应用中打开WPF窗体并且让子窗体显示在Office应用上 彻底关闭Excle进程的几个方法 (七)Net Core项目使用Controller之二

    一张图搞定OAuth2.0   目录 1.引言 2.OAuth2.0是什么 3.OAuth2.0怎么写 回到顶部 1.引言 本篇文章是介绍OAuth2.0中最经典最常用的一种授权模式:授权码模式 非常 ...

  3. 初识sa-token,一行代码搞定登录授权!

    前言 在java的世界里,有很多优秀的权限认证框架,如Apache Shiro.Spring Security 等等.这些框架背景强大,历史悠久,其生态也比较齐全. 但同时这些框架也并非十分完美,在前 ...

  4. 【转】轻松搞定FTP之FlashFxp全攻略

    转载网址:http://www.newhua.com/2008/0603/39163.shtml 轻松搞定FTP之FlashFxp全攻略 导读: FlashFXP是一款功能强大的FXP/FTP软件,融 ...

  5. 如何使用 APM 搞定 PHP 应用的性能优化?

    APM 究竟是什么? 很多人都是第一次听说 APM 的概念,本文主要阐述如何使用 APM 的解决方案来实现 PHP 应用性能的优化.首先先介绍一下 APM (Application Performan ...

  6. 一条SQL搞定信息增益的计算

    欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 周东谕,2011年加入腾讯,现任职于腾讯互娱运营部数据中心,主要从事游戏相关的数据分析和挖掘工作. 信息增益原 ...

  7. 一文搞定scrapy爬取众多知名技术博客文章保存到本地数据库,包含:cnblog、csdn、51cto、itpub、jobbole、oschina等

    本文旨在通过爬取一系列博客网站技术文章的实践,介绍一下scrapy这个python语言中强大的整站爬虫框架的使用.各位童鞋可不要用来干坏事哦,这些技术博客平台也是为了让我们大家更方便的交流.学习.提高 ...

  8. MySQL命令,一篇文章替你全部搞定

    MySQL命令,一篇文章替你全部搞定 MySQL的基本操作可以包括两个方面:MySQL常用语句如高频率使用的增删改查(CRUD)语句和MySQL高级功能,如存储过程,触发器,事务处理等.而这两个方面又 ...

  9. 搞定pycharm专业版的安装

    学习python也有一段时间了,装了python2,也装了python3.对于IDE当然首选了人人拍掌叫好的pycharm.其实作为小白,一开始的时候并不知道什么是IDE,什么是pychram,以为装 ...

随机推荐

  1. 安装Prettier

    安装Prettier Prettier是优化代码格式的工具,可优化JavaScript.TypeScript.JSON等代码及配置文件. 使用命令yarn add -D --exact prettie ...

  2. js 关于setTimeout和Promise执行顺序问题

    js 关于setTimeout和Promise执行顺序问题 异步 -- Promise和setTimeout 执行顺序   Promise 和 setTimeout 到底谁先执行 定时器的介绍 Jav ...

  3. 推荐一些好用的 HTML5 & JavaScript 游戏引擎开发库

    推荐一些好用的 HTML5 & JavaScript 游戏引擎开发库 0. 引言 如果你是一个游戏开发者,并且正在寻找一个可以与 JavaScript 和 HTML5 无缝工作的游戏引擎.那么 ...

  4. 【译】客户端存储(Client-Side Storage)

    本文转载自:众成翻译译者:文蔺链接:http://www.zcfy.cc/article/660原文:http://www.html5rocks.com/en/tutorials/offline/st ...

  5. html 不常用标签介绍

    文本元素 <wbr> 如果单词太长,或者您担心浏览器会在错误的位置换行,那么您可以使用 <wbr> 元素来添加 Word Break Opportunity(单词换行时机).英 ...

  6. 小程序web-view加载H5信息不全

    满足小程序的web-view标签跳转网页形式 配置小程序后台的web-view(业务域名) 可打开关联的公众号的文章 通常实现逻辑 页面加载的时候赋值于一个data对象的值,然后赋值到web-view ...

  7. Git本地上传口令

    $ cd /d/GitProject  (进入要上传的文件的文件夹) $ git pull                 (更新本地库) $ git add .                (添加 ...

  8. 面向对象编程-终结篇 es6新增语法

    各位,各位,终于把js完成了一个段落了,这次的章节一过我还没确定下面要学的内容可能是vue也可能是前后端交互,但无论是哪个都挺兴奋的,因为面临着终于可以做点看得过去的大点的案例项目了,先憋住激动地情绪 ...

  9. Spring-Bean标签属性scope范围

    scope:指对象的作用范围,取值如下 1.singleton:默认值,单例的 2.prototype:多例的 3.request:WEB项目,Spring创建一个Bean的对象,把对象存入到requ ...

  10. centos和redhat的区别

    CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统)是Linux发行版之一,它是来自于Red Hat Enterprise Linu ...