spring boot项目set-cookie不生效

项目迁移后,登录失败,发现sessionId未写入cookie,每次请求生成新session。排查后发现是Tomcat版本问题,从7.0.0升级至8.5.54,问题解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目基于spring boot开发。项目迁移到另外一台服务器之后(迁移是另外一个同事帮忙弄的),忽然发生了登录失败的问题。检擦之后,发现是由于sessionId没有写入到cookie中,倒是每一次请求都会生成一个新的session

尝试了百度的N种方案,均无果。

今天整理项目的文档,顺手查了下项目tomcat的版本,发现这个版本不大对,./version.sh显示是7.0.0,我原来用的不是这个版本,然后捞到本地用version.bat看了下,变成了8.0.30。匪夷所思。

所以干脆就去tomcat官网下载了最新的8.5.54版本,把现网的tomcat换掉了。启动项目,那个set-cookie失效的问题居然不药而愈了。

超开心~

写个博客备忘一下。要是出现这种以前一切正常的项目迁移之后忽然挂掉的问题,各位不妨考虑下是否是中间件的问题?

<think>嗯,用户正在处理一个很典型的SpringBoot应用问题:注册数据入库但无法登录。结合用户提到的外卖点餐系统背景和之前的分析,现在需要聚焦在SpringBoot特有的问题排查上。用户之前已经排除了基础事务问题(注册SQL执行成功),现在要重点检查三个SpringBoot特有的陷阱。首先想到的是SpringSecurity的默认拦截规则——它可能屏蔽了登录请求路径。参考引用[^2]提到SpringBoot简化配置的特性,反而可能导致开发者忽略其默认规则的存在。然后注意到密码处理方式差异。用户系统可能用了passwordEncoder,但没意识到默认实现会添加bcrypt前缀。这点在引用[^3]的登录流程图里特别重要:数据库里的“{bcrypt}”开头的密码值会直接导致普通字符串比对失败。数据库事务的隔离级别也值得深挖。引用[^1]提到SpringBoot的高效性可能让开发者忽略事务细节,比如当使用@Transactional时默认的REPEATABLE_READ隔离级别,可能使得新注册数据对后续查询不可见。特别是用户提到“点餐系统”可能存在高并发场景。突然想到还有个隐藏问题:Vue前端加密。引用[^4]提到Vue.js的响应式特性,如果前端用md5加密密码而后台用bcrypt,这种跨层加密方式不匹配会直接导致认证失败。需要提醒用户检查浏览器Network里的请求体是否包含额外加密字段。解决方案里要强调“立即验证”的技巧。比如在注册controller里直接打印新用户ID,然后用这个ID执行数据库查询,能快速区分是存储问题还是读取问题。如果数据存在但登录失败,九成是认证流程问题;如果数据不存在,就是事务提交问题。</think> 以下是针对Spring Boot外卖点餐系统中**注册成功但无法登录**问题的深度分析与解决方案,结合引用内容整理核心原因及排查路径: --- ### **一、核心问题定位** #### 1. **Spring Security配置问题** [^1][^3] - **典型表现**: 注册成功但访问登录接口返回`403`或重定向循环 - **根因分析**: - Spring Security默认拦截所有请求,未配置白名单 - 登录接口路径与安全配置不匹配(如缺`.permitAll()`) ```java // 错误示例:未开放登录接口 http.authorizeRequests() .antMatchers("/register").permitAll() // 仅放行注册 .anyRequest().authenticated(); // 登录接口被拦截 ``` - 前后端分离下跨域配置未生效(引用[^2][^4]中Vue前端需跨域) #### 2. **密码存储/验证不一致** [^3] - **典型表现**: 登录时提示"密码错误",但数据库记录存在 - **根因分析**: - 注册时未加密 → 登录时校验明文(或反之) - BCrypt加密后未添加前缀`{bcrypt}` ```java // 错误示例:手动加密但未添加前缀 String rawPwd = "123456"; String encodedPwd = passwordEncoder.encode(rawPwd); // 存储值应为:{bcrypt}$2a$10$... ``` - 多密码加密器共存导致验证器选择错误 #### 3. **事务未提交/数据不可见** [^1] - **典型表现**: 注册后立即登录失败,重启服务后能登录 - **根因分析**: - `@Transactional`未正确配置传播级别(如`REQUIRES_NEW`未生效) - MySQL事务隔离级别为`REPEATABLE_READ`时,新会话可能读不到新数据 --- ### **二、系统性解决方案** #### ✅ **步骤1:验证Spring Security配置** ```java // 正确配置登录接口放行 + 跨域 http.csrf().disable() // 测试时可关闭CSRF .authorizeRequests() .antMatchers("/api/login", "/api/register").permitAll() // 开放登录注册 .anyRequest().authenticated() .and() .cors(); // 启用跨域配置 ``` - **验证方法**: 直接访问登录接口URL(如`POST /api/login`),观察是否返回`401`(未授权)而非`403`(禁止访问) #### ✅ **步骤2:统一密码处理规范** ```java // 注册服务层代码 public void register(User user) { user.setPassword("{bcrypt}" + passwordEncoder.encode(user.getPassword())); // 添加前缀 userRepository.save(user); } // 配置Bean确保使用BCrypt @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } ``` - **关键检查点**: 确保数据库密码字段值以`{bcrypt}$`开头(长度至少60字符) #### ✅ **步骤3:强制事务提交** ```java @Transactional(propagation = Propagation.REQUIRES_NEW) // 确保独立事务 public void register(User user) { userRepository.save(user); userRepository.flush(); // 强制同步数据库 } ``` - **排查工具**: 注册后立即在`Navicat`中执行SQL:`SELECT * FROM user WHERE username='xxx' FOR UPDATE`,观察记录是否存在 #### ✅ **步骤4:关键日志埋点** ```java // 登录认证逻辑 public UserDetails loadUserByUsername(String username) { log.info("正在查询用户: {}", username); // ① 确认请求到达 User user = userRepository.findByUsername(username); log.info("用户查询结果: {}", user != null); // ② 验证数据库查询 return user; } ``` --- ### **三、辅助排查工具** | 工具 | 使用场景 | |-------------------|----------------------------------| | **浏览器Network** | 检查登录请求状态码/响应体 | | **H2 Console** | 开发环境实时查库(需配`spring.h2.console.enabled=true`) | | **Actuator** | 监控Bean加载状态 (`/actuator/beans`)| --- ### **四、高频问题扩展** #### 1. **跨域问题(Vue+Spring Boot)** [^2][^4] ```java // 解决Vue跨域:配置CorsFilter @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("http://localhost:8080"); // Vue端口 config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } ``` #### 2. **会话管理失效** - 检查前端:Vue是否存储`JSESSIONID` - 后端配置:`server.servlet.session.cookie.http-only=true` 调试工具:观察登录响应头`Set-Cookie`是否存在 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值