搞定了!OAuth2使用验证码进行授权
现在验证码登录已经成为很多应用的主流登录方式,但是对于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 获取更多资讯
搞定了!OAuth2使用验证码进行授权的更多相关文章
- 如何用python搞定验证码中的噪点
背景:朋友在为"关山口男子职业技术学校"写一款校园应用,于是找MoonXue写一个学生选课系统的登录接口.为了搞定这个接口,不得不先搞定这个系统的验证码. 验证码大概是这个样子 看 ...
- 一张图搞定OAuth2.0 在Office应用中打开WPF窗体并且让子窗体显示在Office应用上 彻底关闭Excle进程的几个方法 (七)Net Core项目使用Controller之二
一张图搞定OAuth2.0 目录 1.引言 2.OAuth2.0是什么 3.OAuth2.0怎么写 回到顶部 1.引言 本篇文章是介绍OAuth2.0中最经典最常用的一种授权模式:授权码模式 非常 ...
- 初识sa-token,一行代码搞定登录授权!
前言 在java的世界里,有很多优秀的权限认证框架,如Apache Shiro.Spring Security 等等.这些框架背景强大,历史悠久,其生态也比较齐全. 但同时这些框架也并非十分完美,在前 ...
- 【转】轻松搞定FTP之FlashFxp全攻略
转载网址:http://www.newhua.com/2008/0603/39163.shtml 轻松搞定FTP之FlashFxp全攻略 导读: FlashFXP是一款功能强大的FXP/FTP软件,融 ...
- 如何使用 APM 搞定 PHP 应用的性能优化?
APM 究竟是什么? 很多人都是第一次听说 APM 的概念,本文主要阐述如何使用 APM 的解决方案来实现 PHP 应用性能的优化.首先先介绍一下 APM (Application Performan ...
- 一条SQL搞定信息增益的计算
欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 周东谕,2011年加入腾讯,现任职于腾讯互娱运营部数据中心,主要从事游戏相关的数据分析和挖掘工作. 信息增益原 ...
- 一文搞定scrapy爬取众多知名技术博客文章保存到本地数据库,包含:cnblog、csdn、51cto、itpub、jobbole、oschina等
本文旨在通过爬取一系列博客网站技术文章的实践,介绍一下scrapy这个python语言中强大的整站爬虫框架的使用.各位童鞋可不要用来干坏事哦,这些技术博客平台也是为了让我们大家更方便的交流.学习.提高 ...
- MySQL命令,一篇文章替你全部搞定
MySQL命令,一篇文章替你全部搞定 MySQL的基本操作可以包括两个方面:MySQL常用语句如高频率使用的增删改查(CRUD)语句和MySQL高级功能,如存储过程,触发器,事务处理等.而这两个方面又 ...
- 搞定pycharm专业版的安装
学习python也有一段时间了,装了python2,也装了python3.对于IDE当然首选了人人拍掌叫好的pycharm.其实作为小白,一开始的时候并不知道什么是IDE,什么是pychram,以为装 ...
随机推荐
- 串联型PID,并联型PID与标准型PID简要说明
PID广泛应用于工业生产各个环节,然而对于不同PID结构会有一些差异,导致在调参时若按照常规的经验调试,结果将会有非常大的不同. 串联型PID(Serial PID) 串联型PID的三个环节由比例,积 ...
- 顺利通过EMC实验(1)
- [CSS]《CSS揭秘》第四章——视觉效果
投影 单侧投影 box-shadow:0px 10px 10px -5px black; 邻边投影 box-shadow:10px 10px 10px 2px black; 双侧投影 box-shad ...
- 小程序 wx.getSystemInfoSync 获取 windowHeight 问题
windowHeight 概念 可使用窗口高度,即:屏幕高度(screenHeight) - 导航(tabbar)高度 存在问题 安卓设备下获取 windowHeight 不能准确得到对应的高度,总是 ...
- 解决vscode开发react项目没有html标签自动补全
怎么设置自动补全: 左下角齿轮按钮--设置-- 在搜索框中输入Include Languages,选择Emmet,并在Emmet:include language下点击在setting.json中编辑 ...
- LC-349
Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the ...
- 【Oracle】EXPDP和IMPDP数据泵进行导出导入的方法
一.expdp/impdp和exp/imp 客户端工具 1.exp和imp是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. 服务端工具 2.expdp和impdp是服务端的工具程序,他们 ...
- POP3协议(电子邮件邮局协议)中UIDL和TOP命令在实际使用中的作用
POP3是电子邮件协议中用于接收邮件的协议,相较于发送邮件的SMTP协议,POP3的命令要多一些.主要的命令有LIST.STAT.RETR.DELE.UIDL.TOP.QUIT,以及用于登录邮箱的US ...
- thymeleaf模板使用
使用模板页面,实现在同一个页面展现不同数据,controller实现页面跳转的时候就不在需要打开新页面
- uniapp中添加vant组件
首先是npm i vant@2 -S 下载vant包 接下来就是找到main.js引入vant 然后就是在页面中直接使用 会发现没有样式 最后再找到app.vue再style里面全局引入vant的样式 ...