• SpringBoot实现登录拦截器


    对于管理系统或其他需要用户登录的系统,登录验证都是必不可少的环节,在SpringBoot开发的项目中,通过实现拦截器来实现用户登录拦截并验证。

    1、SpringBoot实现登录拦截的原理

    SpringBoot通过实现HandlerInterceptor接口实现拦截器,通过实现WebMvcConfigurer接口实现一个配置类,在配置类中注入拦截器,最后再通过@Configuration注解注入配置.

    1.1、实现HandlerInterceptor接口

    实现HandlerInterceptor接口需要实现3个方法:preHandlepostHandleafterCompletion.

    3个方法各自的功能如下:

    1. package blog.interceptor;
    2. import blog.entity.User;
    3. import org.springframework.web.servlet.HandlerInterceptor;
    4. import org.springframework.web.servlet.ModelAndView;
    5. import javax.servlet.http.HttpServletRequest;
    6. import javax.servlet.http.HttpServletResponse;
    7. import javax.servlet.http.HttpSession;
    8. public class UserLoginInterceptor implements HandlerInterceptor {
    9. /***
    10. * 在请求处理之前进行调用(Controller方法调用之前)
    11. */
    12. @Override
    13. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    14. System.out.println("执行了拦截器的preHandle方法");
    15. try {
    16. HttpSession session = request.getSession();
    17. //统一拦截(查询当前session是否存在user)(这里user会在每次登录成功后,写入session)
    18. User user = (User) session.getAttribute("user");
    19. if (user != null) {
    20. return true;
    21. }
    22. response.sendRedirect(request.getContextPath() + "login");
    23. } catch (Exception e) {
    24. e.printStackTrace();
    25. }
    26. return false;
    27. //如果设置为false时,被请求时,拦截器执行到此处将不会继续操作
    28. //如果设置为true时,请求将会继续执行后面的操作
    29. }
    30. /***
    31. * 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
    32. */
    33. @Override
    34. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    35. System.out.println("执行了拦截器的postHandle方法");
    36. }
    37. /***
    38. * 整个请求结束之后被调用,也就是在DispatchServlet渲染了对应的视图之后执行(主要用于进行资源清理工作)
    39. */
    40. @Override
    41. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    42. System.out.println("执行了拦截器的afterCompletion方法");
    43. }
    44. }

    preHandle在Controller之前执行,因此拦截器的功能主要就是在这个部分实现:

    • 检查session中是否有user对象存在;

    • 如果存在,就返回true,那么Controller就会继续后面的操作;

    • 如果不存在,就会重定向到登录界面。就是通过这个拦截器,使得Controller在执行之前,都执行一遍preHandle.

    1.2、实现WebMvcConfigurer接口,注册拦截器

    实现WebMvcConfigurer接口来实现一个配置类,将上面实现的拦截器的一个对象注册到这个配置类中.

    1. package blog.config;
    2. import blog.interceptor.UserLoginInterceptor;
    3. import org.springframework.context.annotation.Configuration;
    4. import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
    5. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    6. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    7. @Configuration
    8. public class LoginConfig implements WebMvcConfigurer {
    9. @Override
    10. public void addInterceptors(InterceptorRegistry registry) {
    11. //注册TestInterceptor拦截器
    12. InterceptorRegistration registration = registry.addInterceptor(new UserLoginInterceptor());
    13. registration.addPathPatterns("/**"); //所有路径都被拦截
    14. registration.excludePathPatterns( //添加不拦截路径
    15. "/login", //登录路径
    16. "/**/*.html", //html静态资源
    17. "/**/*.js", //js静态资源
    18. "/**/*.css" //css静态资源
    19. );
    20. }
    21. }

    将拦截器注册到了拦截器列表中,并且指明了拦截哪些访问路径,不拦截哪些访问路径,不拦截哪些资源文件;最后再以@Configuration注解将配置注入。

    1.3、保持登录状态

    只需一次登录,如果登录过,下一次再访问的时候就无需再次进行登录拦截,可以直接访问网站里面的内容了。

    在正确登录之后,就将user保存到session中,再次访问页面的时候,登录拦截器就可以找到这个user对象,就不需要再次拦截到登录界面了.

    1. @RequestMapping(value = {"", "/", "/index"}, method = RequestMethod.GET)
    2. public String index(Model model, HttpServletRequest request) {
    3. User user = (User) request.getSession().getAttribute("user");
    4. model.addAttribute("user", user);
    5. return "users/index";
    6. }
    7. @RequestMapping(value = {"/login"}, method = RequestMethod.GET)
    8. public String loginIndex() {
    9. return "users/login";
    10. }
    11. @RequestMapping(value = {"/login"}, method = RequestMethod.POST)
    12. public String login(@RequestParam(name = "username")String username, @RequestParam(name = "password")String password,
    13. Model model, HttpServletRequest request) {
    14. User user = userService.getPwdByUsername(username);
    15. String pwd = user.getPassword();
    16. String password1 = MD5Utils.md5Code(password).toUpperCase();
    17. String password2 = MD5Utils.md5Code(password1).toUpperCase();
    18. if (pwd.equals(password2)) {
    19. model.addAttribute("user", user);
    20. request.getSession().setAttribute("user", user);
    21. return "redirect:/index";
    22. } else {
    23. return "users/failed";
    24. }
    25. }

    2、代码实现及示例

    代码实现如上所示。

    在登录成功之后,将user信息保存到session中,下一次登录时浏览器根据自己的SESSIONID就可以找到对应的session,就不要再次登录了,可以从Chrome浏览器中看到。

    3、效果验证 

    3.1、访问localhost:8081/index页面:

    被重定向到了localhost:8081/login,实现了登录拦截。 

    3.2、正确输入用户名和密码登录

    3.3、再次访问localhost:8081/index 

    没有再次被登录拦截器拦截,证明可以保持登录。 

  • 相关阅读:
    重磅!顶象发布《城市消费券安全调研报告》
    Python的self作用,以及__init__,__new__
    精通C语言:打造高效便捷的通讯录管理系统
    【博客484】alertmanager-----告警处理源码剖析
    QTableView样式设置
    CentOS 编译安装 nginx
    Hadoop概述
    GPT实战系列-ChatGLM2部署Ubuntu+Cuda11+显存24G实战方案
    Linux--网络概念
    docker之设置代理
  • 原文地址:https://blog.csdn.net/LU58542226/article/details/133095262