Filter实现登录验证拦截功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Filter实现登录验证拦截功能相关的知识,希望对你有一定的参考价值。

既然是 Filter 实现的登录验证,首先自然是创建 Filter 实现类了,但是在创建 Filter 之前,我们先来看一个问题:怎么判断用户是否登录了?

看我们的登录代码:

@RequestMapping("/login")
public String login(LoginModel login, HttpServletRequest req, HttpServletResponse res, Model model) {
    HttpSession session = req.getSession();
    login.setPassword(Tools.md5(Constant.MD5_PREFIX + login.getPassword()));
    //验证账号和密码
    UserModel user = userManager.getUserByLoginInfo(login);
    if (user == null) {
        model.addAttribute("message", "用户名密码错误");
        return "/login";
    }
    //设置session用户信息
    session.setAttribute(Constant.SESSION_USER_ID, user.getId());
    return "redirect:/index";
}

验证用户名和密码之后,向 session 添加一个属性 userId,session 表示用户浏览器和服务器之间的会话,有这个 userId 表示用户已经登录过,没有说明用户没有登录。

然后我们来创建 LoginFilter 类

public class LoginFilter implements Filter {
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        HttpSession session = req.getSession();
        String userId = (String) session.getAttribute(Constant.SESSION_USER_ID);
        
        String uri = req.getRequestURI();//已登录
        if (userId != null && !"".equals(userId)) {
            if ("/".equals(uri) || "/login".equals(uri)) {
                res.sendRedirect("/index"); return;
            } else {
                chain.doFilter(request, response); return;
            }
        }//正常请求,跳转至登录页面
        if ("/".equals(uri) || "/login".equals(uri)) {
            chain.doFilter(request, response); return;
        }
        res.sendRedirect("/"); return;
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
    }
}

Filter 就根据 session 中的 userId 来判断该怎么跳转。

应该注意的是,很多请求是不需要登录身份就可以访问的,比如登录请求、验证码、静态资源等。Filter 应该予以放行

String uri = req.getRequestURI();
String[] greenLights = {"/resources/*","/vcodeimg","/api/*"};
//静态资源、验证码、api服务放行
if (isGreenLightUri(uri, greenLights)) {
    chain.doFilter(request, response); return;
}

isGreenLightUri()方法:

boolean isGreenLightUri(String uri, String[] greenlights) {
    if (uri == null) return false;
    if (greenlights == null || greenlights.length == 0) return false;
        
    for (String greenlight : greenlights) {
        if (greenlight.endsWith("*")) { //标有*号的需要模糊匹配
            String str = greenlight.substring(0, greenlight.length()-2);
            if (uri.startsWith(str)) return true;
        }
        if (uri.equals(greenlight)) return true;
    }
    return false;
}

实现了 Filter 之后,需要在 web.xml 中配置,让 Filter 生效

<filter>
  <filter-name>loginFilter</filter-name>
  <filter-class>org.uc.web.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>loginFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

注意:LoginFilter 要放在最前面

以上是关于Filter实现登录验证拦截功能的主要内容,如果未能解决你的问题,请参考以下文章

Filter学习

SSM项目使用拦截器实现登录验证功能

SpringBoot中基于拦截器实现登录验证功能

Filter&Listener

Filter

Filter