
你好我是fengxin_rou这是我的个人主页fengxin_rou的主页❄️欢迎查看我的专栏我的专栏《Java后端学习》、《JAVASE基础》、《JUC并发》、《redis》、《JVM虚拟机》、《MYSQL》、《黑马点评》、《rabbitmq》、《JavaWebAI的talis学习系统》、《苍穹外卖》目录前言一、模块基础Java Record 与统一配置中心1.1 Java Record 简化 DTO 开发1.2 统一认证配置 AuthProperties二、安全核心加密算法与 JWT 令牌实现2.1 BCrypt 密码加密企业级标准2.2 JWT 令牌签发与验证2.3 PEM 密钥读取工具三、权限控制Spring Security 安全配置3.1 核心安全配置3.2 CORS 跨域配置四、支撑能力验证码与刷新令牌管理4.1 Redis 验证码存储与防刷4.2 Refresh Token 白名单机制五、业务核心登录注册完整流程5.1 标识标准化关键细节5.2 发送验证码5.3 用户注册5.4 双模式登录5.5 令牌刷新5.6 重置密码5.7 密码策略校验5.8 正则格式校验六、结语前言在前后端分离与微服务架构下认证授权模块是系统安全的核心入口。本文基于 Spring Boot Spring Security 实现一套完整的登录、注册、验证码、令牌管理方案采用JWT 无状态认证、BCrypt 密码加密、Redis 存储验证码与刷新令牌兼顾安全性、易用性与扩展性可直接用于企业级项目落地。一、模块基础Java Record 与统一配置中心1.1 Java Record 简化 DTO 开发Java 16 提供的Record是一种极简数据载体类会自动生成构造器、getter、equals、hashCode、toString大幅减少样板代码非常适合定义 DTO、VO 等只读数据对象。// 用户认证响应 DTO public record AuthUserResponse( Long id, String nickname, String avatar, String phone, String zhId, LocalDate birthday, String school, String bio, String gender, String tagJson ) {}使用示例// 直接构建对象 AuthUserResponse user new AuthUserResponse(123L, 张三, ...); // 自动生成无 get 前缀的 getter Long userId user.id(); String nick user.nickname();1.2 统一认证配置 AuthProperties通过ConfigurationProperties绑定 YML 配置统一管理 JWT、验证码、密码策略支持配置文件覆盖默认值实现配置与代码解耦。application.yml 核心配置yamlauth: jwt: issuer: zhiquang # 签发者 key-id: zhiguang-key # 密钥ID private-key: classpath:keys/private.pem public-key: classpath:keys/public.pem access-token-ttl: PT15M # 访问令牌15分钟 refresh-token-ttl: P7D # 刷新令牌7天 verification: code-length: 6 # 验证码长度 ttl: PT5M # 有效期5分钟 max-attempts: 5 # 最大尝试次数 send-interval: PT60S # 发送间隔60秒 daily-limit: 10 # 每日上限10条 password: bcrypt-strength: 12 # 加密强度 min-length: 8 # 最小长度8位配置绑定类Data ConfigurationProperties(prefix auth) public class AuthProperties { private final Jwt jwt new Jwt(); private final Verification verification new Verification(); private final Password password new Password(); Data public static class Jwt { private String issuer zhiquang; private Duration accessTokenTtl Duration.ofMinutes(15); private Duration refreshTokenTtl Duration.ofDays(7); private String keyId zhiguang-key; private Resource privateKey; private Resource publicKey; } }二、安全核心加密算法与 JWT 令牌实现2.1 BCrypt 密码加密企业级标准普通哈希SHA256速度极快易被暴力破解与彩虹表攻击。BCrypt自带随机盐、可调整计算成本、故意降低运算速度是密码存储的行业标准。Configuration EnableConfigurationProperties(AuthProperties.class) RequiredArgsConstructor public class AuthConfiguration { private final AuthProperties properties; /** * 密码加密器 Bean */ Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder( properties.getPassword().getBcryptStrength() ); } }使用方式// 注册加密密码 String encoded passwordEncoder.encode(rawPassword); // 登录校验密码 boolean match passwordEncoder.matches(rawPassword, encodedPassword);2.2 JWT 令牌签发与验证JWTJSON Web Token由Header头部、Payload负载、Signature签名三部分组成采用RSA 非对称加密私钥签发令牌公钥验证令牌防止篡改。核心 Bean 实现/** * JWT 编码器用于签发令牌 */ Bean public JwtEncoder jwtEncoder() { AuthProperties.Jwt jwtProps properties.getJwt(); RSAPrivateKey privateKey PemUtils.readPrivateKey(jwtProps.getPrivateKey()); RSAPublicKey publicKey PemUtils.readPublicKey(jwtProps.getPublicKey()); RSAKey rsaKey new RSAKey.Builder(publicKey) .privateKey(privateKey) .keyID(jwtProps.getKeyId()) .build(); JWKSourceSecurityContext jwkSource new ImmutableJWKSet(new JWKSet(rsaKey)); return new NimbusJwtEncoder(jwkSource); } /** * JWT 解码器用于验证令牌 */ Bean public JwtDecoder jwtDecoder() { RSAPublicKey publicKey PemUtils.readPublicKey(properties.getJwt().getPublicKey()); return NimbusJwtDecoder.withPublicKey(publicKey).build(); }令牌设计Access Token有效期 15 分钟用于接口资源访问Refresh Token有效期 7 天仅用于刷新 Access Token令牌自带用户信息、过期时间、签发者服务端无需存储会话2.3 PEM 密钥读取工具PemUtils 用于读取 RSA 密钥文件将 PEM 格式密钥转为 Java 可识别的RSAPrivateKey/RSAPublicKey为 JWT 签名提供密钥支持。三、权限控制Spring Security 安全配置3.1 核心安全配置采用无状态 JWT 认证关闭 CSRF、开启 CORS、禁用 Session适配前后端分离架构。Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf(AbstractHttpConfigurer::disable) // 关闭 CSRF .cors(Customizer.withDefaults()) // 开启跨域 // 无状态会话 .sessionManagement(session - session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) ) .authorizeHttpRequests(auth - auth // 放行认证相关接口 .requestMatchers(/api/v1/auth/**).permitAll() .requestMatchers(/actuator/health, /api/v1/knowposts/feed).permitAll() .anyRequest().authenticated() ) // 开启 JWT 资源服务校验 .oauth2ResourceServer(oauth - oauth.jwt(Customizer.withDefaults())); return http.build(); }3.2 CORS 跨域配置支持前后端分离跨域请求生产环境需将allowedOrigins设为业务域名白名单。Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config new CorsConfiguration(); config.setAllowedOrigins(List.of(*)); // 生产替换为白名单 config.setAllowedMethods(List.of(GET, POST, PUT, DELETE, OPTIONS)); config.setAllowedHeaders(List.of(Authorization, Content-Type)); config.setAllowCredentials(false); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return source; }四、支撑能力验证码与刷新令牌管理4.1 Redis 验证码存储与防刷使用 Redis Hash 结构存储验证码、尝试次数、最大尝试次数实现发送频率限制、每日上限、错误次数限制。// 验证码校验核心逻辑 Override public VerificationCheckResult verify(String scene, String identifier, String code) { String key buildKey(scene, identifier); HashOperationsString, String, String ops redisTemplate.opsForHash(); MapString, String data ops.entries(key); // 校验验证码是否存在、是否匹配、尝试次数是否超限 }验证码服务流程校验手机号 / 邮箱格式检查发送间隔与日上限生成 6 位数字验证码存入 Redis 并设置过期时间调用发送器发送短信 / 邮件4.2 Refresh Token 白名单机制JWT 无法主动失效通过Redis 白名单实现刷新令牌的主动撤销、轮换、登出解决 JWT 安全痛点。刷新流程Access Token 过期 → 前端携带 Refresh Token 请求/refresh后端校验令牌合法性 Redis 白名单是否存在验证通过 → 签发新令牌对 撤销旧 Refresh Token验证失败 → 返回未登录强制重新登录五、业务核心登录注册完整流程5.1 标识标准化关键细节统一处理用户输入手机号去空格、邮箱转小写避免因格式不一致导致重复注册、查询失败。// 标识标准化 private String normalizeIdentifier(IdentifierType type, String value) { if (type PHONE) { return value.trim().replaceAll(\\s, ); } else if (type EMAIL) { return value.trim().toLowerCase(); } return value.trim(); }5.2 发送验证码按场景做存在性校验注册场景账号必须不存在登录 / 重置密码场景账号必须已存在5.3 用户注册public AuthResponse register(RegisterRequest request) { // 1. 校验协议、标识格式、验证码 // 2. 标准化标识校验唯一性 // 3. 密码策略校验 BCrypt 加密 // 4. 保存用户信息 // 5. 签发 Access Refresh 令牌 // 6. 记录登录审计日志 // 7. 返回用户信息 令牌 }5.4 双模式登录支持密码登录验证码登录密码登录匹配加密后哈希值验证码登录校验 Redis 中验证码登录成功统一签发令牌5.5 令牌刷新public TokenResponse refresh(TokenRefreshRequest request) { // 1. 解码 Refresh Token 并校验类型 // 2. 检查 Redis 白名单是否有效 // 3. 签发新令牌对 // 4. 撤销旧 Refresh Token // 5. 存储新令牌到白名单 }5.6 重置密码验证验证码 → 更新密码 →撤销该用户所有 Refresh Token→ 强制全端重新登录提升账号安全性。5.7 密码策略校验private void validatePassword(String password) { // 非空、长度 ≥8、包含字母数字 boolean hasLetter password.chars().anyMatch(Character::isLetter); boolean hasDigit password.chars().anyMatch(Character::isDigit); if (!hasLetter || !hasDigit) { throw new BusinessException(密码必须包含字母和数字); } }5.8 正则格式校验// 手机号正则 private static final Pattern PHONE_PATTERN Pattern.compile(^1\\d{10}$); // 邮箱正则 private static final Pattern EMAIL_PATTERN Pattern.compile(^[A-Z0-9._%-][A-Z0-9.-]\\.[A-Z]{2,}$, Pattern.CASE_INSENSITIVE);六、结语本文完整实现了企业级 Spring Boot 登录注册认证模块以 Spring Security 为权限底座、JWT 为无状态令牌、BCrypt 保障密码安全、Redis 支撑高并发验证码与令牌管理覆盖注册、登录、验证码、令牌刷新、密码重置、安全校验全流程。该方案具备高安全、无状态、易扩展、易部署特点适用于电商、社交、管理后台、微服务网关等场景。后续可扩展多因素认证、第三方登录、接口限流、日志审计、异常登录检测等能力进一步提升系统安全等级。