JavaWeb 使用Filter实现自动登录
程序员文章站
2022-05-07 11:00:26
思路 使用cookie存储账号、密码,使用Filter拦截,从cookie中取出账号、密码。若用户要注销|登出、不再想使用自动登录,将cookie的有效期设置为0即可。 浏览器可以查看Cookie,不能直接存储账号、密码的明文,使用Cookie存储账号、密码时需要加密,从Cookie中取出来时需要解 ......
思路
使用cookie存储账号、密码,使用filter拦截,从cookie中取出账号、密码。若用户要注销|登出、不再想使用自动登录,将cookie的有效期设置为0即可。
浏览器可以查看cookie,不能直接存储账号、密码的明文,使用cookie存储账号、密码时需要加密,从cookie中取出来时需要解密。
每次http请求都使用filter拦截,从cookie中解密出账号、密码,每次都要解密,浪费时间。第一次从cookie中解密出账号、密码后,可以将账号、密码放到session域中,会话期间直接从session中取,不必再解密。
登录页面
<form action="loginservlet" method="post"> 用户名:<input type="text" name="user" /><br /> 密码:<input type="password" name="pwd" /><br /> <button type="submit">登录</button><br /> ${requestscope.errormsg} </form>
el表达式没有空指针异常,没有时返回空串。所以没有errormsg时, ${requestscope.errormsg} 也不会出错。
将登录页面设为项目初始页面
<welcome-file-list> <welcome-file>/login.jsp</welcome-file> </welcome-file-list>
处理登录表单的servlet
1 @webservlet("/loginservlet") 2 public class loginservlet extends httpservlet { 3 protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { 4 string user=request.getparameter("user"); 5 string pwd=request.getparameter("pwd"); 6 7 //连接数据库,检查是否正确 8 //...... 9 if (true){ 10 //放到session中 11 httpsession session = request.getsession(); 12 session.setattribute("user",user); 13 session.setattribute("pwd","pwd"); 14 15 //将值加密后存储在cookie中,此处略过加密 16 cookie cookie=new cookie("autologin",user+"-"+pwd); 17 //整个项目中可用 18 cookie.setpath(request.getcontextpath()); 19 //这个域名地址下的所有webapp都可用 20 //cookie.setpath("/"); 21 cookie.setmaxage(60*60*24*7); 22 response.addcookie(cookie); 23 24 //重定向到目标页面。request.getcontextpath()获取的是当前web应用的根目录 25 response.sendredirect(request.getcontextpath()+"/index.jsp"); 26 //不能这样写,这样写表示域名下的index.jsp,不是域名/web应用/index.jsp。 27 //response.sendredirect("/index.jsp"); 28 } 29 else{ 30 //转发到登录页面,附加错误信息 31 request.setattribute("errormsg","账户名或密码错误"); 32 request.getrequestdispatcher("/login").forward(request,response); 33 } 34 35 } 36 37 protected void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { 38 dopost(request,response); 39 } 40 }
首页
<h2>hello,${sessionscope.user}</h2>
filter实现自动登录
1 @webfilter("/*") 2 public class handlerfilter implements filter { 3 public void destroy() { 4 } 5 6 public void dofilter(servletrequest req, servletresponse resp, filterchain chain) throws servletexception, ioexception { 7 //统一全站编码 8 req.setcharacterencoding("utf-8"); 9 resp.setcontenttype("text/html;charset=utf-8"); 10 11 //servletrequest不能获取session、cookie,需要强转为httpservletrequest 12 httpservletrequest httpreq = (httpservletrequest) req; 13 14 //检查session中有没有用户信息 15 httpsession session = httpreq.getsession(); 16 if (session.getattribute("user")==null){ 17 //如果session中没有,从cookie中找autologin。可能是会话结束后再次访问,比如离开网站30min(session默认超时时间)后再次访问、关闭浏览器后重新打开再次访问。 18 cookie[] cookies = httpreq.getcookies(); 19 //需要先检测cookies是否为null,为null时会报空指针异常 20 if (cookies!=null){ 21 for (cookie cookie:cookies){ 22 if (cookie.getname().equals("autologin")) { 23 //需要先解密,此处略过 24 //...... 25 string[] userinfo=cookie.getvalue().split("-"); 26 session.setattribute("user",userinfo[0]); 27 session.setattribute("pwd",userinfo[1]); 28 } 29 } 30 } 31 } 32 33 chain.dofilter(req, resp); 34 } 35 36 public void init(filterconfig config) throws servletexception { 37 38 } 39 40 }
处理注销 | 登出 | 不再使用自动登录 的servlet
1 @webservlet("/logoutservlet") 2 public class logoutservlet extends httpservlet { 3 protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { 4 //从session中移出用户信息 5 httpsession session = request.getsession(); 6 session.removeattribute("user"); 7 session.removeattribute("pwd"); 8 9 //删除cookie,此处采用同名覆盖,也可以遍历获取,再将有效期设为0 10 cookie cookie=new cookie("autologin",""); 11 cookie.setpath(request.getcontextpath()); 12 cookie.setmaxage(0); 13 response.addcookie(cookie); 14 } 15 16 protected void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { 17 dopost(request,response); 18 } 19 }
推荐阅读