news 2026/4/24 1:50:19

若依RuoYi-Vue项目实战:手把手教你给后台管理系统加上短信登录(Spring Security深度适配)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
若依RuoYi-Vue项目实战:手把手教你给后台管理系统加上短信登录(Spring Security深度适配)

若依RuoYi-Vue项目实战:Spring Security深度整合短信登录全流程解析

在当今企业级后台管理系统开发中,多因素认证已成为提升安全性的标配方案。本文将基于若依(RuoYi-Vue)这一流行开源框架,详细拆解如何在不破坏原有账号密码体系的前提下,优雅地集成短信验证码登录功能。不同于简单的API对接,我们将重点解决Spring Security架构下的身份认证流程改造问题,特别针对实际开发中容易遇到的用户查询SQL优化、异常处理规范等痛点提供工业级解决方案。

1. 技术方案设计与核心组件

1.1 Spring Security认证流程重构

Spring Security的默认认证流程基于UsernamePasswordAuthenticationFilter设计,要实现短信登录需要理解其核心扩展点:

// 认证流程伪代码 AuthenticationManager.authenticate() → AuthenticationProvider.supports() → AuthenticationProvider.authenticate() → UserDetailsService.loadUserByUsername()

针对短信登录的特殊性,我们需要定制以下组件:

  • 自定义Token:替代UsernamePasswordAuthenticationToken
  • 专属Provider:处理短信验证码认证逻辑
  • 扩展UserDetailsService:支持手机号查询用户

1.2 关键类关系设计

组件类型默认实现短信登录实现职责说明
AuthenticationTokenUsernamePasswordAuthenticationTokenSmsCodeAuthenticationToken封装认证请求信息
AuthenticationProviderDaoAuthenticationProviderSmsCodeAuthenticationProvider执行具体认证逻辑
UserDetailsService默认实现UserDetailsByPhonenumberServiceImpl按手机号加载用户信息

2. 核心代码实现

2.1 自定义认证Token实现

创建继承自AbstractAuthenticationToken的短信认证Token:

public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken { private final Object principal; // 存储手机号码 public SmsCodeAuthenticationToken(Object principal) { super(null); this.principal = principal; setAuthenticated(false); } @Override public Object getCredentials() { return null; // 验证码已在前置校验环节处理 } // 其他必要方法实现... }

注意:这里credentials返回null是因为验证码校验应在进入Provider前完成

2.2 用户查询服务增强

改造用户查询服务,确保手机号查询与用户名查询保持相同安全级别:

@Service("userDetailsByPhonenumber") public class UserDetailsByPhonenumberServiceImpl implements UserDetailsService { @Autowired private ISysUserService userService; @Override public UserDetails loadUserByUsername(String phoneNumber) { SysUser user = userService.selectUserByPhonenumber(phoneNumber); // 状态检查逻辑与账号密码登录保持一致 if (user == null) { throw new ServiceException("手机号未注册"); } // 账户状态校验逻辑... return createLoginUser(user); } }

对应的Mapper查询应添加适当索引:

ALTER TABLE sys_user ADD INDEX idx_phonenumber (phonenumber);

3. Spring Security配置改造

3.1 认证提供者注册

在Security配置类中注入自定义组件:

@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public SmsCodeAuthenticationProvider smsCodeAuthenticationProvider() { return new SmsCodeAuthenticationProvider(userDetailsService); } @Override protected void configure(AuthenticationManagerBuilder auth) { auth.authenticationProvider(smsCodeAuthenticationProvider()); } }

3.2 认证入口配置

添加短信登录专属端点:

@Override protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore( new SmsCodeAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class); // 原有配置保持不变... }

4. 业务层关键实现

4.1 验证码发送服务

实现带防刷机制的验证码发送:

@PostMapping("/sendSmsCode/{phoneNumber}") public AjaxResult sendSmsCode(@PathVariable String phoneNumber) { // 频率控制(Redis实现) String rateLimitKey = "sms:limit:" + phoneNumber; Long count = redisTemplate.opsForValue().increment(rateLimitKey); if (count != null && count == 1) { redisTemplate.expire(rateLimitKey, 1, TimeUnit.MINUTES); } if (count > 3) { throw new ServiceException("操作过于频繁"); } // 生成并发送验证码 String code = generateRandomCode(); smsService.send(phoneNumber, code); // 存储验证码(带时效) String uuid = UUID.randomUUID().toString(); redisTemplate.opsForValue().set( "sms:code:" + uuid, code, 5, TimeUnit.MINUTES); return AjaxResult.success().put("uuid", uuid); }

4.2 登录接口实现

@PostMapping("/smsLogin") public AjaxResult smsLogin(@RequestBody SmsLoginDto dto) { // 验证码校验 String cacheCode = redisTemplate.opsForValue() .get("sms:code:" + dto.getUuid()); if (!dto.getSmsCode().equals(cacheCode)) { throw new CaptchaException(); } // 执行Spring Security认证 Authentication authentication = authenticationManager.authenticate( new SmsCodeAuthenticationToken(dto.getPhoneNumber())); // 生成JWT令牌 LoginUser loginUser = (LoginUser) authentication.getPrincipal(); String token = tokenService.createToken(loginUser); return AjaxResult.success().put(Constants.TOKEN, token); }

5. 前端适配与联调技巧

5.1 Vue组件改造要点

在登录页面添加短信登录选项卡:

<el-tabs v-model="activeTab"> <el-tab-pane label="账号密码" name="password"> <!-- 原有表单 --> </el-tab-pane> <el-tab-pane label="短信登录" name="sms"> <el-form @submit.native.prevent="handleSmsLogin"> <el-form-item prop="phoneNumber"> <el-input v-model="smsForm.phoneNumber" placeholder="手机号"/> </el-form-item> <el-form-item prop="smsCode"> <el-input v-model="smsForm.smsCode" placeholder="验证码"> <template #append> <el-button @click="sendSmsCode" :disabled="isCountingDown"> {{ countdown > 0 ? `${countdown}s` : '获取验证码' }} </el-button> </template> </el-input> </el-form-item> </el-form> </el-tab-pane> </el-tabs>

5.2 常见联调问题排查

  1. 跨域问题:确保新增接口在Spring Security的白名单中
  2. 认证流程中断:检查过滤器链顺序是否正确
  3. Redis键冲突:使用命名空间隔离不同业务的缓存键
  4. 事务一致性:用户查询与登录记录要保持原子性

6. 生产环境增强建议

6.1 安全加固措施

  • 启用HTTPS防止验证码被截获
  • 实施IP风控策略(如Fail2ban)
  • 添加图形验证码二次验证
  • 敏感操作增加短信二次确认

6.2 性能优化方案

// 使用管道化操作提升Redis性能 List<Object> results = redisTemplate.executePipelined( (RedisCallback<Object>) connection -> { for (String key : keys) { connection.get(key.getBytes()); } return null; });

对于高并发场景,建议:

  1. 采用异步日志记录
  2. 实现本地缓存+Redis的多级缓存
  3. 对短信服务进行降级处理

在用户量超过10万的系统中,我们通过以下优化使登录接口的TP99从320ms降至90ms:

  • 用户信息缓存预热
  • 验证码Redis集群分片
  • Nginx层请求合并
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 1:50:19

追觅:从清洁电器到太空卫星,俞浩的科技野心能否实现?

【追觅超级碗的惊人承诺】追觅&#xff08;Dreame&#xff0c;发音类似 "dreamy"&#xff09;利用超级碗半分钟曝光时间&#xff0c;承诺带来令人眼花缭乱的产品进化&#xff0c;从扫地机器人、割草机到超级跑车、人形机器人&#xff0c;甚至迈向太空。变形金刚风格的…

作者头像 李华
网站建设 2026/4/24 1:48:54

3步掌握硬件性能调优:Universal-x86-Tuning-Utility完全指南

3步掌握硬件性能调优&#xff1a;Universal-x86-Tuning-Utility完全指南 【免费下载链接】Universal-x86-Tuning-Utility Unlock the full potential of your Intel/AMD based device. 项目地址: https://gitcode.com/gh_mirrors/un/Universal-x86-Tuning-Utility 你是否…

作者头像 李华
网站建设 2026/4/24 1:47:53

Ubuntu 22.04 LTS 实时计算与机密计算技术解析

1. Ubuntu 22.04 LTS "Jammy Jellyfish" 深度解析作为一名长期跟踪Linux发行版演进的技术博主&#xff0c;我第一时间在物理机和云环境实测了Ubuntu 22.04 LTS。这个代号为"Jammy Jellyfish"的版本不仅是常规升级&#xff0c;更在工业级实时计算、机密计算…

作者头像 李华
网站建设 2026/4/24 1:46:51

ESP32与SI4684打造开源DAB+接收器全解析

1. 开源硬件DAB接收器项目概述PE5PVB团队开发的这款基于ESP32和Skyworks SI4684芯片的开源DAB接收器&#xff0c;为无线电爱好者提供了一个可完全自定义的数字广播解决方案。DAB作为FM/AM广播的数字升级版本&#xff0c;在欧洲、澳大利亚等地区已经形成成熟覆盖网络&#xff08…

作者头像 李华
网站建设 2026/4/24 1:46:50

爆火 GPT-image-2 加持!AI 短剧带货系统,多平台矩阵自动引流

一、GPT-image-2 引爆 AI 内容赛道&#xff0c;短剧带货成流量新洼地2026 年 4 月&#xff0c;OpenAI 重磅发布GPT-image-2模型&#xff0c;凭借原生推理生成、商用级画质、中文精准渲染三大核心优势&#xff0c;迅速刷屏全网&#xff0c;直接带火 AI 短剧带货赛道。作为 DALL-…

作者头像 李华