You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:18:41