详解JavaEE使用过滤器实现登录(用户自动登录 安全登录 取消自动登录黑用户禁止登录)

详解JavaEE使用过滤器实现登录

什么是过滤器

在网络开发中,过滤器是一种能够截取并处理请求和响应的功能组件。过滤器可以修改请求,修改响应内容并可以过滤/拦截请求和响应。使用过滤器可以在不影响原来的请求和响应方式的情况下增加一些自定义的操作,使得整个系统的设计更加灵活。

怎样使用过滤器实现登录

1. 过滤器的实现

过滤器需要实现Filter接口,接口中有三个方法:

  • init 方法:过滤器的初始化方法。
  • doFilter 方法:过滤器要执行的操作。
  • destroy 方法:过滤器销毁时执行的方法。

下面是过滤器的一个基本实现:

public class LoginFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {

    }

    @Override
    public void destroy() {

    }
}

2. 登录账号认证

在登录操作中,我们需要对用户的账号和密码进行认证。下面是一个使用Filter实现用户登录的过滤器:

public class LoginFilter implements Filter{
    private String loginPage = "/login.jsp";
    private String encoding = "UTF-8";
    private String[] logonPages = new String[] { "/login.jsp", "/index.jsp" };

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

        String loginPages = filterConfig.getInitParameter("loginPages");
        if (loginPages != null && !"".equals(loginPages)) {
            logonPages = loginPages.split(",");
        }
        String loginPage = filterConfig.getInitParameter("loginPage");
        if (loginPage != null && !"".equals(loginPage)) {
            this.loginPage = loginPage;
        }
        String encoding = filterConfig.getInitParameter("encoding");
        if (encoding != null && !"".equals(encoding)) {
            this.encoding = encoding;
        }
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        String requestURI = req.getRequestURI();
        boolean loginPageFlag = false;
        for (String page : logonPages) {
            if (requestURI.indexOf(page) != -1) {
                loginPageFlag = true;
                break;
            }
        }

        if (!loginPageFlag) {
            // 进入这里表示登录失败或者还没有登录,需要进行登录认证
            HttpSession session = req.getSession();
            String userId = (String) session.getAttribute("userId");
            if (userId == null) {
                // 进行登录认证
                userId = req.getParameter("userId");
                String password = req.getParameter("password");
                if (userId != null && !"".equals(userId) 
                    && password != null && !"".equals(password) 
                    && validate(userId, password)) {
                    // 认证通过,设置session
                    session.setAttribute("userId", userId);

                    // 安全登录
                    if (req.getParameter("remember") != null) {
                        // 在Cookie中存储用户名密码
                        Cookie loginCookie = new Cookie("login", URLEncoder.encode(userId + ":" + password, encoding));
                        loginCookie.setMaxAge(60 * 60 * 24 * 7);
                        res.addCookie(loginCookie);
                    }

                    filterChain.doFilter(request, response);
                } else {
                    // 非法登录,直接返回登录页面
                    res.sendRedirect(req.getContextPath() + loginPage);
                }
            } else {
                // 用户已经登录,可以访问
                filterChain.doFilter(request, response);
            }
        } else {
            // 请求的是登录页面,可以直接访问
            filterChain.doFilter(request, response);
        }
    }

    private boolean validate(String userId, String password) {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

}

3. 用户自动登录

在实现登录的过程中,为了方便用户下次访问的时候能够直接访问系统而无需再次登录,我们可以实现用户自动登录功能。下面是用户自动登录的实现过程:

3.1 在Cookie中存储用户信息

在用户登录后,我们在Cookie中存储用户的用户名和密码,方便用户下次访问时可直接登录。代码如下:

if (req.getParameter("remember") != null) {
    // 在Cookie中存储用户名密码
    Cookie loginCookie = new Cookie("login", URLEncoder.encode(userId + ":" + password, encoding));
    loginCookie.setMaxAge(60 * 60 * 24 * 7);
    res.addCookie(loginCookie);
}

3.2 在Filter中判断Cookie中是否有用户信息

在每次请求时,我们都需要从Cookie中获取用户的信息,如果Cookie中有用户信息,则自动登录。代码如下:

// 判断是否需要自动登录
Cookie[] cookies = req.getCookies();
if (cookies != null && cookies.length > 0) {
    for (Cookie cookie : cookies) {
        if ("login".equals(cookie.getName())) {
            String userInfo = URLDecoder.decode(cookie.getValue(), encoding);
            String[] loginInfo = userInfo.split(":");
            String username = loginInfo[0];
            String password = loginInfo[1];
            if (validate(username, password)) {
                HttpSession session = req.getSession();
                session.setAttribute("userId", username);
            }
        }
    }
}

4. 安全登录

在实现自动登录功能后,为了保证用户密码安全,我们需要对密码进行加密。代码如下:

4.1 密码加密

在用户登录时,使用Base64对用户的密码进行加密:

if (userId != null && !"".equals(userId) 
    && password != null && !"".equals(password) 
    && validate(userId, password)) {
    // 认证通过,设置session
    session.setAttribute("userId", userId);

    // 安全登录
    if (req.getParameter("remember") != null) {
        // 对密码进行加密
        String encryptPassword = Base64.getEncoder().encodeToString(password.getBytes(encoding));
        // 在Cookie中存储用户名密码
        Cookie loginCookie = new Cookie("login", URLEncoder.encode(userId + ":" + encryptPassword, encoding));
        loginCookie.setMaxAge(60 * 60 * 24 * 7);
        res.addCookie(loginCookie);
    }

    filterChain.doFilter(request, response);
} else {
    // 非法登录,直接返回登录页面
    res.sendRedirect(req.getContextPath() + loginPage);
}

4.2 密码解密

在自动登录时,我们需要对Base64加密后的密码进行解密:

// 判断是否需要自动登录
Cookie[] cookies = req.getCookies();
if (cookies != null && cookies.length > 0) {
    for (Cookie cookie : cookies) {
        if ("login".equals(cookie.getName())) {
            String userInfo = URLDecoder.decode(cookie.getValue(), encoding);
            String[] loginInfo = userInfo.split(":");
            String username = loginInfo[0];
            String password = loginInfo[1];

            // 对密码进行解密
            String decryptPassword = new String(Base64.getDecoder().decode(password), encoding);

            if (validate(username, decryptPassword)) {
                HttpSession session = req.getSession();
                session.setAttribute("userId", username);
            }
        }
    }
}

5. 取消自动登录

如果用户选择了自动登录选项,但是在下次访问时不想继续启用自动登录,我们需要提供给用户一个取消自动登录的按钮。代码如下:

登录页面中的取消自动登录按钮:

<div class="checkbox">
    <label for="remember-me">
        <input type="checkbox" name="remember" id="remember-me"> 自动登录
    </label>
    <br>
    <a href="${pageContext.request.contextPath}/CancelAutoLoginServlet">取消自动登录</a>
</div>

实现取消自动登录功能的Servlet:

public class CancelAutoLoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public CancelAutoLoginServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 删除Cookie中的登录信息
        Cookie loginCookie = new Cookie("login", "");
        loginCookie.setMaxAge(0);
        response.addCookie(loginCookie);

        response.sendRedirect(request.getContextPath() + "/login.jsp");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

小结

通过使用过滤器实现登录相关功能,可以很容易地实现用户的安全登录、自动登录等功能。可以增强系统的安全性,提升用户的使用体验,但是需要注意保护用户的隐私信息。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JavaEE使用过滤器实现登录(用户自动登录 安全登录 取消自动登录黑用户禁止登录) - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • 详解SpringBoot中的统一异常处理

    下面我将为你详细讲解“详解SpringBoot中的统一异常处理”的完整攻略。 什么是SpringBoot中的统一异常处理 在SpringBoot中,我们经常需要对抛出的异常进行统一处理。如果我们每个地方都去捕捉异常,并进行相应处理,那么代码量会非常大。此时,我们可以使用SpringBoot中的统一异常处理,将所有异常集中处理,大大减少了代码量,也方便了我们对…

    Java 2023年5月27日
    00
  • Java内部类原理、概述与用法实例详解

    Java内部类原理、概述与用法实例详解 Java中的内部类是指嵌套在另外一个类内部的类,它们提供了更好的封装和代码组织方式。本文将详细讲解Java内部类的原理、概述和用法实例,并提供两个示例来说明其使用和优势。 内部类原理 Java中的内部类实际上是一种成员类,它与其他成员变量和成员方法一样隶属于其外围类,并可以访问外围类的私有数据和方法,甚至可以访问到其外…

    Java 2023年5月23日
    00
  • Java Web中ServletContext对象详解与应用

    下面我将为你详细讲解Java Web中ServletContext对象的完整攻略。 什么是ServletContext对象 ServletContext是Java Web容器中的一个重要对象,它代表整个Web应用程序,一个Web应用程序只有一个ServletContext对象。ServletContext对象在Web应用程序启动时被创建,在Web应用程序停止…

    Java 2023年6月15日
    00
  • 实例讲解Java读取一般文本文件和word文档的方法

    让我来为大家详细讲解一下实例讲解Java读取一般文本文件和word文档的方法。 1. 读取一般文本文件 Java读取一般文本文件的方式很简单,可以使用File类和Scanner类。 1.1 使用File类读取文本文件 参照以下代码: import java.io.BufferedReader; import java.io.FileReader; impor…

    Java 2023年5月19日
    00
  • Java JVM编译策略案例详解

    当我们编写Java程序时,代码是无法直接被计算机识别的,需要通过一种特殊的编译器将其转换成可被计算机执行的字节码,而Java虚拟机(JVM)则负责将字节码解释为对应的机器指令并执行。在这个过程中,JVM的编译器对字节码的编译策略扮演着重要的角色,选择合适的编译策略有助于提高程序执行效率。下面将详细讲解Java JVM编译策略的攻略,包括编译模式、编译等级、缓…

    Java 2023年5月19日
    00
  • SpringSecurity导致SpringBoot跨域失效的问题解决

    首先需要明确的是,Spring Boot是默认开启CSRF保护的。而Spring Security也是默认开启CSRF保护的。当二者共存时,常常会产生CSRF保护机制引起的跨域问题。那么如何解决SpringSecurity导致SpringBoot跨域失效的问题呢?下面给出完整攻略。 1. 禁用Spring Security的CSRF保护 第一种解决方式是禁用…

    Java 2023年5月20日
    00
  • 用headjs来管理和加载js 提高网站加载速度

    使用headjs来管理和加载JS可以提高网站的加载速度,这是因为headjs通过异步加载JS文件来提高页面渲染的速度。下面是使用headjs来管理和加载JS的完整攻略: 1. 下载并引入headjs 首先,需要下载head.js库,并在网页中引入该文件,可以使用CDN来引入该文件,如下所示: <script src="https://cdn.…

    Java 2023年6月15日
    00
  • JavaSpringBoot报错“MethodArgumentTypeMismatchException”的原因和处理方法

    当使用Java的Spring Boot框架时,可能会遇到“MethodArgumentTypeMismatchException”错误。这个错误通常是由以下原因之一引起的: 参数类型不匹配:如果控制器方法的参数类型与请求参数类型不匹配,则可能会出现此错误。在这种情况下,需要确保控制器方法的参数类型与请求参数类型匹配。 参数格式不正确:如果请求参数格式不正确,…

    Java 2023年5月5日
    00
合作推广
合作推广
分享本页
返回顶部