Java用户登录注册模块的核心是密码安全存储、会话状态管理、输入校验边界;须用BCryptPasswordEncoder加密密码,JWT替代HttpSession,数据库与代码层双重校验唯一性,重置密码需一次性时效令牌。
Java 用户登录注册模块不是套模板就能跑通的,核心在于「密码安全存储」「会话状态管理」「输入校验边界」这三处,任一环节出错都会导致账号系统形同虚设。
BCryptPasswordEncoder
很多人用 MD5 或 SHA-256 自行加盐哈希,这是错的——这些算法太快,容易被暴力破解。Spring Security 提供的 BCryptPasswordEncoder 是专为密码设计的自适应慢哈希。
实操建议:
10~12),值越大越慢但越安全:BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(12);
passwordEncoder.encode(rawPassword) 存入数据库字段(如 user.password_hash)passwordEncoder.matches(inputPassword, dbHash) 校验,不要自己比对字符串BCrypt 的哈希值里已包含盐和轮次信息,直接存完整字符串即可HttpSession 做唯一凭证传统 HttpSession 在分布式部署下会失效,且无法控制令牌过期、强制下线。现代 Java 项目应优先用 JWT 或 Spring Security 的 Bearer Token 流程。
实操建议:
access_token 和 expires_in,token 由 JwtEncoder 签发,载荷中至少含 user_id、role、exp
Authorization: Bearer
@EnableWebSecurity + JwtAuthenticationFilter 拦截并解析,不要依赖 session.getAttribute("user")
ip_hash),且设置 maxInactiveInterval 合理(如 1800 秒)username 和 email 字段要双重唯一约束,且校验时机要分层仅靠数据库 UNIQUE 约束不够:用户提交时得即时反馈,不能等插入失败才报错;同时要防

实操建议:
ALTER TABLE user ADD UNIQUE (username); 和 ALTER TABLE user ADD UNIQUE (email);
userRepository.findByUsernameOrEmail(username, email),避免因唯一约束抛 DataIntegrityViolationException
username ≤ 32 字符)、禁用空格和特殊符号(正则:^[a-zA-Z0-9_]{3,32}$)@NotBlank + @Pattern 注解校验,但注意:注解只在校验层生效,DB 层仍需约束兜底直接“找回密码”并邮件发原密码是严重安全错误。正确做法是生成一次性的、带过期时间的重置令牌(reset token),且该令牌不能映射到明文密码或旧密码哈希。
实操建议:
UUID.randomUUID().toString()),存入数据库 password_reset_tokens 表,关联 user_id + expires_at(建议 15 分钟)https://yoursite.com/reset?token=abc123,不要带任何用户标识参数BCryptPasswordEncoder 重新加密新密码,再清空该 token 记录@Data 类中敏感字段加 @ToString.Exclude
真正难的不是写完登录接口,而是每个环节都得想清楚“攻击者会怎么绕过”。比如邮箱校验是否可被伪造、token 是否可被重放、密码重置链接有没有绑定 IP 或设备指纹——这些细节不补上,系统上线即高危。