详解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技术站