Spring MVC会话问题求助:如何为登录控制器添加会话?
解决Spring MVC会话验证与路径访问问题
我来帮你梳理下问题并给出具体的实现方案:你当前的核心问题是未登录状态下能直接访问/user/aboutme/1,但访问/user却无法进入,这说明/user路径大概率需要登录验证,但你的LoginController还没有处理会话登录状态的逻辑,导致系统无法识别用户是否已登录。下面是一步步的具体操作:
1. 完善LoginController的会话登录逻辑
首先要在登录验证成功后,把用户信息存入HttpSession,标记用户的登录状态:
@Controller public class LoginController { // 注入你的用户服务类,用于验证账号密码 @Autowired private UserService userService; @GetMapping("/login") public String login(Model model) { model.addAttribute("title", "Login Page"); return "user/login"; } // 处理登录表单的POST请求 @PostMapping("/login") public String processLogin(@RequestParam String username, @RequestParam String password, HttpSession session, RedirectAttributes redirectAttrs) { // 调用服务层验证用户账号密码是否正确 User user = userService.validateUser(username, password); if (user != null) { // 验证成功,将用户信息存入会话 session.setAttribute("loggedInUser", user); // 登录成功后重定向到/user路径 return "redirect:/user"; } else { // 验证失败,返回错误提示 redirectAttrs.addFlashAttribute("error", "Invalid username or password"); return "redirect:/login"; } } }
2. 添加会话拦截器,保护需要登录的路径
创建一个拦截器,用来拦截请求并验证会话中的登录状态,确保只有登录用户才能访问/user这类受保护的路径:
第一步:编写拦截器类
public class SessionInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 从会话中获取当前登录用户 User loggedInUser = (User) request.getSession().getAttribute("loggedInUser"); String requestURI = request.getRequestURI(); // 拦截未登录用户访问/user路径,重定向到登录页 if (requestURI.equals("/user") && loggedInUser == null) { response.sendRedirect("/login"); return false; } // 针对/user/aboutme/{id}的逻辑(可根据业务需求调整) if (requestURI.startsWith("/user/aboutme/")) { // 提取路径中的用户ID String userIdStr = requestURI.split("/")[3]; Long userId = Long.parseLong(userIdStr); // 允许登录用户访问自己的详情页,未登录用户暂时放行(和你当前行为一致) if (loggedInUser != null && loggedInUser.getId().equals(userId)) { return true; } else if (loggedInUser == null) { return true; } else { // 禁止登录用户访问他人详情页,可根据需求修改 response.sendRedirect("/user"); return false; } } // 其他路径默认放行 return true; } }
第二步:注册拦截器到Spring配置
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new SessionInterceptor()) // 拦截所有请求,在拦截器内部做具体判断 .addPathPatterns("/**"); } }
3. 完善UserController的逻辑
确保/user路径的控制器能正确处理登录状态:
@Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @GetMapping public String userHome(Model model, HttpSession session) { User loggedInUser = (User) session.getAttribute("loggedInUser"); // 双重保险,防止拦截器失效时未登录用户进入 if (loggedInUser == null) { return "redirect:/login"; } model.addAttribute("user", loggedInUser); model.addAttribute("title", "User Home"); return "user/home"; } @GetMapping("/aboutme/{id}") public String userAboutMe(@PathVariable Long id, Model model) { // 根据ID查询用户信息(这里用你的业务逻辑实现) User user = userService.getUserById(id); model.addAttribute("user", user); model.addAttribute("title", "About Me"); return "user/aboutme"; } }
4. 补充登录页面的表单(可选但必要)
确保你的user/login.html页面有正确的登录表单,提交到登录的POST接口:
<form th:action="@{/login}" method="post"> <div> <label>Username:</label> <input type="text" name="username" required/> </div> <div> <label>Password:</label> <input type="password" name="password" required/> </div> <!-- 显示登录错误提示 --> <div th:if="${error}" style="color: red;">[[${error}]]</div> <button type="submit">Login</button> </form>
这样配置后,未登录用户访问/user会被重定向到登录页,登录成功后存入会话就能正常访问;而/user/aboutme/1的访问逻辑可以根据你的业务需求灵活调整(比如是否允许匿名访问、是否限制只能访问自己的详情页)。
内容的提问来源于stack exchange,提问作者Shadox
相关产品推荐
相关产品推荐

