展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

自定义认证机制,使用手机短信验证

起步

  • 简介
手机号登录是不需要密码的,通过短信验证码实现免密登录功能
1. 向手机发送手机验证码,使用第三方短信平台 SDK 发送,如: 阿里云短信服务(阿里大于)
2. 登录表单输入短信验证码
3. 使用自定义过滤器 MobileValidateFilter
4. 当验证码校验通过后,进入自定义手机认证过滤器 MobileAuthenticationFilter 校验手机号是否存在
5. 自定义 MobileAuthenticationToken 提供给 MobileAuthenticationFilter
6. 自定义 MobileAuthenticationProvider 提供给 ProviderManager 处理
7. 创建针对手机号查询用户信息的 MobileUserDetailsService ,交给 MobileAuthenticationProvider
8. 自定义 MobileAuthenticationConfig 配置类将上面组件连接起来,添加到容器中
9. 将 MobileAuthenticationConfig 添加到 SpringSecurityConfig 安全配置的过滤器链上。

  • security认证流程
# 首先发送请求会进入AuthenticationFilter,由AuthenticationFilter生成一个UserNamepasswordAuthenticationToken
# 之后UserNamepasswordAuthenticationToken进入AuthenticationManager
# AuthenticationManager主要进行认证
# AuthenticationManager中有多个AuthenticationProviders
# 每个AuthenticationProviders是不同的认证机制
# 之后通过UserDetailsService查询数据库获取用户信息
# 最后按原来的流程将认证成功后的用户信息放到Authentication中

发送手机验证码

  • 生成验证码
code模块编写接口SmsSend
code模块编写实现类SmsCodeSender实现SmsSend
code模块编写SecurityConfigBean,专门用于注入bean,即指定对应的发送验证码实现类
# 例如之后不使用SmsCodeSender实现类,在web模块编写新的实现MobileSmsCodeSender,并添加注解@Component
# 那么就会使用MobileSmsCodeSender实现了
  • 获取验证码
code模块编写MobileLoginController,放行对应的接口
浏览器发送请求测试http://localhost:8080/codeMobile?mobile=15123206957
测试通过
web模块的MobileSmsCodeSender类放开@Component注解
浏览器再次发送请求测试http://localhost:8080/codeMobile?mobile=15123206957
测试通过

手机短信验证

# code模块编写MobileValidateFilter;用于校验输入的验证码是否正确
# code模块编写MobileAuthenticationFilter;用于判断数据库中是否有该手机号的用户,生成自定义的MobileAuthenticationToken
# code模块编写MobileAuthenticationToken,编写MobileAuthenticationToken的生成方法
# code模块编写MobileAuthenticationProvider,编写自己的认证机制
# web模块编写MobileUserDetailsService,用于查询手机号的用户信息和权限,最后封装成UserDetails对象
# code模块编写MobileAuthenticationConfig,用于组合其他关于手机登录的组件,例如认证成功的处理,记住我功能
# code模块中SpringSecurityConfig类,将filter注入进去
@Autowired
private MobileValidateFilter mobileValidateFilter;
@Autowired
private MobileAuthenticationConfig mobileAuthenticationConfig;
# 添加到UsernamePasswordAuthenticationFilter这个过滤器之前
.addFilterBefore(mobileValidateFilter, UsernamePasswordAuthenticationFilter.class)
# 将手机认证添加到过滤器
http.apply(mobileAuthenticationConfig);
# 启动测试,控制台未报错

测试

# 打开cmd,使用curl测试
# 输入1个正确的验证码
curl localhost:8080/mobileForm -X POST -d "mobile=15123206957&code=123456"
# 控制台打印
11:30:26.169 INFO 19144 --- [io-8080-exec-10] c.y.s.a.mobile.MobileValidateFilter : 登录时输入的短信验证码为:123456
11:30:26.171 INFO 19144 --- [io-8080-exec-10] c.y.s.service.MobileUserDetailsService : 请求的手机号是:15123206957
CustomAuthenticationSuccessHandler ---> success
# 输入1个错误的验证码
curl localhost:8080/mobileForm -X POST -d "mobile=15123206957&code=123455"
# 控制台打印如下
11:30:53.492 INFO 19144 --- [nio-8080-exec-2] c.y.s.a.mobile.MobileValidateFilter : 登录时输入的短信验证码为:123455
CustomAuthenticationFailureHandler ---> error

整合记住我功能

# MobileAuthenticationConfig中添加如下
mobileAuthenticationFilter.setRememberMeServices(http.getSharedObject(RememberMeServices.class));
# MobileUserDetailsService中封装用户信息时,不应该将手机号封装进去,应该将查询到的用户名封装进去
return new User("chen", "", true, true, true, true,
AuthorityUtils.commaSeparatedStringToAuthorityList("ADMIN"));

拓展

  • 使用这种方式,也可以实现邮箱验证码登录
posted @   DogLeftover  阅读(198)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示