自动登录功能十分常见,以下对个人用的一种方法进行分析
基本知识
Cookie
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器,当用户使用浏览器再去访问服务器中的web资源时,会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。通俗讲,就是把上网留下的一些数据存放到磁盘中或者域中,然后下次上网就能自动加载一些数据。
Cookie API
Javax.servlet.http.Cookie类用于创建一个Cookie,response接口也定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。同样,request接口中也定义了一个getCookie方法,它用于获取客户端提交的cookie
Public Cookie(String name, String value)
setValue与getValue方法
setMaxAge与getMaxAge方法setPath与getPath方法
setDomain与getDomain方法
getName方法自动登录
各种网站上都可以捡到,方面用户操作,但设计的不好或操作不当容易造成安全隐患,令用户信息泄漏。
实现分析
关键在于设计到底存放什么东西在Cookie里面,引用网上的说法:
Cookie只是一个普通的文本文件,那里面包含的字符串可以直接用记事本打开并进行编辑。因此任何人在任何电脑上都可以伪造一个包含有他人用户名 的 Cookie,从而实现对他人身份的冒用。要解决这个问题,就要在Cookie中附加一项信息,这个信息需要具有以下特性:1、和该用户一一对应;2、伪 造难度大。这些内容和用户名一起,以Cookie的形式发送给用户的浏览器。并且,服务器必须能够记住这项内容,以便用户再次访问的时候进行核对。
理论上,可以使用该用户的密码。密码具备了前述的两个特点。但是因为Cookie本身未经加密,保存于其中的密码(应该加密)可以被任何人看到,因此这个方法极不安全。
另一种可以加以利用的信息是用户访问时的Session id。因为Session id是一个由系统随机产生的、无规律的、长度较长的字符串,因此它很难被伪造。要把它和用户对应起来,我们需要在数据库中添加一个表,这个表至少有两个字 段,一个是用户名,一个是Session id。当用户首次登录的时候,我们把当前的Session id和用户名分别用Cookie发送给用户,同时,把这两项作为一条记录插入数据库。这样,当用户再次访问的时候,服务器就可以读取客户端发来的这两个 Cookie,并且用它们的值和数据库中的记录比对。如果在数据库中找到了相应记录,就说明这台电脑的确是该用户上次登录时使用的电脑,进而可以为该用户自动登录。
个人就以useriD作为存放在Cookie中的数据为例,展示如何实现。
代码没有经过严格分层,使用静态数据模拟数据库。
代码部分
User.java
public class User { private String userId; private String username; private String password; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
LoginServlet.java
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.UUID; @WebServlet(name = "LoginServlet", urlPatterns = "/LoginServlet") public class LoginServlet extends HttpServlet { public static List<User> data = null; public static User getData(String userId){ for(int i=0; data!=null && i<data.size(); i++) { User user = data.get(i); if(user.getUserId().equalsIgnoreCase(userId)){ return user; } } return null; } @Override public void init() throws ServletException { super.init(); data = new ArrayList<User>(); for (int i = 0; i < 3; i++) { User user = new User(); user.setUserId(UUID.randomUUID().toString()); user.setUsername(i + "" + i); user.setPassword(i + "" + i); data.add(user); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); for(int i=0; data!=null && i < data.size(); i++) { User user = data.get(i); if(user.getUsername().equalsIgnoreCase(username) && user.getPassword().equalsIgnoreCase(password)){ String loginTimeStr = request.getParameter("loginTime"); Integer loginTime = 0; if (loginTimeStr != null) { loginTime = Integer.parseInt(loginTimeStr); } Cookie cookie = new Cookie("autoLogin", user.getUserId()); cookie.setMaxAge(loginTime*24*60*60); response.addCookie(cookie); request.getSession().setAttribute("username", username); request.getRequestDispatcher("login.jsp").forward(request, response); } } throw new RuntimeException("账号密码错误"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
AutoLoginFilter.java
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebFilter(filterName = "AutoLoginFilter", urlPatterns = "/*") public class AutoLoginFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; if(request.getSession().getAttribute("user")!=null){ chain.doFilter(request, response); return; } String value = null; Cookie cookies[] = request.getCookies(); for(int i=0; cookies!=null && i<cookies.length; i++){ if(cookies[i].getName().equalsIgnoreCase("autoLogin")){ value = cookies[i].getValue(); } } if(value!=null){ User user = LoginServlet.getData(value); if(user!=null) request.getSession().setAttribute("username", user.getUsername()); } chain.doFilter(request, response); } public void destroy() { // TODO Auto-generated method stub } public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } }
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Login</title> </head> <body> <div> <form action="${pageContext.request.contextPath}/LoginServlet" method="post"> <p>帐号:<input type="text" name="username" /></p><br/> <p>密码:<input type="password" name="password" /></p><br/> <p>记住账号: <input type="radio" name="loginTime" value="7" checked="checked" />一周 <input type="radio" name="loginTime" alue="3" />三天 <input type="radio" name="loginTime" value="0" />永不 </p><br /> <input type="submit"/> </form> </div> <label>${sessionScope.username}</label> </body> </html>
完