自动登录
在用户登录后进入首页,关闭浏览器后,下次打开浏览器进入首页时往往需要重新登录。
自动登录功能:再次打开浏览器的时候,不需要重新登录就可以进入首页。
实现原理
用户登录后,将用户的用户名和密码保存到Cookie中发送给浏览器,浏览器下次再访问的时候会把cookie内容带回来,服务器从Cookie中取出用户名和密码进行验证,如果验证通过,允许进入首页,从而达到自动登录的目的。
代码实现
首页index.jsp:
<%@ page contentType="text/html;charset=utf-8"%>
<html>
<head>
<title>test</title>
</head>
<body>
<body>
欢迎你:${sessionScope.username }
</body>
</body>
</html>
登录页面login.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="login">
用户名:<input type="text" name="username" ><br>
密码:<input type="text" name="password" ><br>
自动登录:<input type="checkbox" name="auto" value="auto" ><br>
<input type="submit" value="登录">
</form>
</body>
</html>
模拟后台登录的Service方法:
package pers.zhang.service;
/**
* @author zhang
* @date 2019/9/21 - 9:46
*/
public class LoginServiceImpl {
public boolean login(String username,String password) {
//假设从数据库中查出的用户名为root,密码为1234
return "root".equals(username)&&"1234".equals(password);
}
}
控制器LoginServlet:
package pers.zhang.servlet;
import pers.zhang.service.LoginServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author zhang
* @date 2019/9/21 - 9:48
*/
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
String auto = request.getParameter("auto"); //是否自动登录
if(new LoginServiceImpl().login(username, password)) {//如果登录成功
request.getSession().setAttribute("username", username);
if(auto==null) {//未勾选自动登录
Cookie cookie = new Cookie("auto", null);
cookie.setMaxAge(60*60*24);//cookie有效时间
cookie.setPath(request.getContextPath()+"/");
response.addCookie(cookie);
}else {//勾选自动登录
Cookie cookie = new Cookie("auto", username+"_"+password);
cookie.setMaxAge(60*60*24);//cookie有效时间
cookie.setPath(request.getContextPath()+"/");
response.addCookie(cookie);
}
//登录成功,跳转
response.sendRedirect("index.jsp");
}else {
//未登录成功,重新登录
response.sendRedirect("login.jsp");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
配置:
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>pers.zhang.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
实现自动登录的过滤器LoginFilter:
package pers.zhang.filter;
import pers.zhang.service.LoginServiceImpl;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import pers.zhang.utils.CookieUtil;
/**
* @author zhang
* @date 2019/9/21 - 9:56
*/
public class LoginFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
if(request.getRequestURI().contains("login")) {//如果访问login,直接放行
chain.doFilter(request, response);
return;
}else {
String username = (String) request.getSession().getAttribute("username");
if(username==null) {//sesion中没有,去Cookie中找
String val = CookieUtil.getCookieValByKey("auto", request);
if(val!= null&& !val.equals("")) {
String name = val.split("_")[0];
String pass = val.split("_")[1];
if(new LoginServiceImpl().login(name, pass)) {//重新验证登录
request.getSession().setAttribute("username", name);//登录成功,放入Session,并放行
chain.doFilter(request, response);
return;
}else {//验证失败,重新登录
response.sendRedirect("login.jsp");
}
}else {//Cookie中也没有,第一次访问,跳转登录页面
response.sendRedirect("login.jsp");
}
}else {//session中有,放行
chain.doFilter(request, response);
return;
}
}
}
public void init(FilterConfig config) throws ServletException {
}
}
配置:
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>pers.zhang.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
从Cookie中获取用户名的工具类CookieUtil:
package pers.zhang.utils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
/**
* @author zhang
* @date 2019/9/21 - 9:57
*/
public class CookieUtil {
public static String getCookieValByKey(String key, HttpServletRequest request) {
String value = null;
Cookie[] cookies = request.getCookies();
if(cookies!= null && cookies.length>0) {
for (Cookie cookie : cookies) {
if(key.equals(cookie.getName())){
value = cookie.getValue();
}
}
}
return value;
}
}
测试:
启动服务器,访问login.jsp:
点击登录,成功后跳转index.jsp:
退出浏览器,再次打开重新访问index.jsp:
自动登录成功!
注 意 : 在 实 际 开 发 中 , 用 户 名 和 密 码 不 是 明 文 放 在 c o o k i e 中 的 , 需 要 先 进 行 加 密 处 理 后 再 存 入 c o o k i e 中 。 \color{red}{注意:在实际开发中,用户名和密码不是明文放在cookie中的,需要先进行加密处理后再存入cookie中。} 注意:在实际开发中,用户名和密码不是明文放在cookie中的,需要先进行加密处理后再存入cookie中。