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

yizhihongxing

详解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日

相关文章

  • Java中Stream流去除List重复元素的方法

    首先要说明一下,Java中的Stream流是Java8中新增的一种函数式操作流程,主要用来对集合进行函数式操作,它可以对集合进行一些链式操作,比如筛选、分组、排序、去重等。 List去重,在Java8中,可以借助Stream流,具体步骤如下: 使用Stream.builder()来构造一个Stream.Builder对象; 通过builder对象调用add方…

    Java 2023年5月31日
    00
  • 全面解析Java支持的数据类型及Java的常量和变量类型

    全面解析Java支持的数据类型及Java的常量和变量类型 Java支持的基本数据类型 Java支持八种基本数据类型,分别是:byte、short、int、long、float、double、char和boolean。具体说明如下: byte:8位有符号整数类型。用于节省内存,适合于低级数据。 short:16位有符号整数类型。和byte类似,被用于节省空间。…

    Java 2023年5月26日
    00
  • Spring Boot+Mybatis的整合过程

    Spring Boot和MyBatis是两个非常流行的Java框架,它们可以很好地协同工作。在本攻略中,我们将详细讲解如何将Spring Boot和MyBatis整合,以及如何使用它们来构建一个完整的Web应用程序。 整合过程 1. 添加依赖 首先,我们需要在pom.xml文件中添加Spring Boot和MyBatis的依赖。以下是一个示例: <de…

    Java 2023年5月14日
    00
  • Java复制文件常用的三种方法

    当需要将一个文件复制到另一个地方时,Java中有许多方法可以复制文件。接下来我将讲解Java中复制文件的常用三种方法。 方法一: 使用Java IO的流来复制文件 最传统的方法是使用Java IO的流来复制文件。此方法使用基本的文件输入/输出流,将源文件作为输入流,将目标文件作为输出流进行复制。 public static boolean copyFileU…

    Java 2023年5月20日
    00
  • 利用SpringMVC和Ajax实现文件上传功能

    利用SpringMVC和Ajax实现文件上传功能 在 Web 应用程序中,文件上传功能是非常常见的需求。本文将详细讲解如何利用 SpringMVC 和 Ajax 实现文件上传功能,包括如何配置 SpringMVC、如何编写前端代码、如何编写后端代码等,并提供两个示例说明。 配置 SpringMVC 在 SpringMVC 中,我们需要配置 Multipart…

    Java 2023年5月18日
    00
  • Java连接mysql数据库的详细教程(推荐)

    Java连接mysql数据库的详细教程 1. 准备工作 在开始连接数据库前,需要先准备好以下材料:1. 安装并启动mysql数据库;2. 下载并安装JDBC驱动。 2. 导入JDBC驱动 在编写Java代码之前,需要先导入JDBC驱动。可以从官方网站下载mysql JDBC驱动包,在项目中添加该jar包。 <dependency> <gro…

    Java 2023年5月19日
    00
  • Spring security实现对账户进行加密

    下面我将为您介绍如何使用 Spring Security 实现对账户进行加密的完整攻略。 什么是 Spring Security? Spring Security 是一个基于 Spring 框架的安全框架,可以为 Web 应用程序和服务添加身份验证和授权支持。 密码加密的必要性 将密码进行加密可以防止密码泄露,增加安全性。在 Spring Security …

    Java 2023年5月20日
    00
  • 最新手机号码、电话号码正则表达式

    作为网站作者,在网站上提供合适的正则表达式能够帮助用户更好地填写信息,本文将详细讲解如何编写符合实际需求的最新手机号码、电话号码正则表达式。 最新手机号正则表达式 先介绍最新的中国手机号码格式:手机号码为11位数字,以13、14、15、17、18、19开头。其中,17、19开头是最新的号段。而且还有一些虚拟运营商的号码前缀不在以上号码段中,例如:170等。 …

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