【杂谈】Remember-Me的实现
前言
此篇随笔记录了Remember-Me实现过程中出现的问题和解决方案,以及相关的思考。
正文
1. RememberMe是什么?
RememberMe意为记住我,对应登录界面的那个勾选项。另一种说法,就是自动登录。
2. 那什么又是自动登录呢?
我们知道Tomcat或者其他Servlet容器的会话都是有时限的,比如Tomcat的会话时间为30分钟,如果30分钟内没有访问,会话将被清除,这时候就不满足登录状态了。那你发出下一个请求,按照正常逻辑就会被拦截下来,告知你没有登录,然后跳转到登录界面让你重新登录。自动登录做的就是,当会话过期后,请求会根据Cookie信息实现透明登录。也就是重新又登录了一遍,产生了一个新的会话。但是在用户看来,他根本不知道发生了什么,而且重新登录的过程中不需要再让用户输入账号密码。
3. 为什么不把会话时间调大一点呢?
Tomcat的会话时间是可配置的。你可以设置成3天或者更久。但是这样就加大了服务器的开销。你设置3天,意味着一个HttpSession将会由Tomcat保留3天。(这里到底是保存在内存还是磁盘尚不确定,运行时内存的可能比较大),前面说了RemememberMe其实是自动登录,也就是说,它不会影响会话存在的时间。而且新会话的产生只能由新的请求触发。
如果用户登录后只浏览了10分钟,就挂着不动了,在都没有进行登出操作的情况下。对比一下两种方案的最大开销(服务端保留无用会话的时间)
第一种:3天会话时间 => 3天 - 10分钟 => 3*24*60 - 10 = 4310 分钟
第二种:30分钟会话时间(默认) => 30 - 10 分钟 = 20分钟
4. RememberMe的原理是什么?
本质上就是Cookie。在登录成功后,如果用户有勾选“记住我”,则服务端在响应中加上Remember-Me的cookie,让浏览器保存一段时间,如7天。在7天之内,如果用户会话过期,可凭此实现透明的重新登录。
5. Cookie中包含哪些内容呢?
1. 用户账号 => 不然无法知道谁要登录,而且需要依此获取密码,生成新签名进行比对
2. 过期时间 => 过期的时间节点,即如果浏览器没有及时自动清除此cookie,服务端收到后要据此删除。
3. 与密码有关的签名 => 如果没有密码的相关信息,那就很容易地通过伪造cookie,来登录其他人的账号。但是密码又不能是明文,必须经过加密。而且不能或者不能太容易被解开。
6. Spring Security中的Cookie格式
Base64(username:expireTime:MD5(username:expireTime:password:secretKey))
其中,签名signature由username、expireTime、password、secretKey组成的字符串,进过MD5加密而成。随后再整合username、expireTime利用Base64编码而成,Base64是可解码的。最终结果,基本上就是一条乱码了。
7. Cookie有了,服务端要怎么处理呢?
那就是Filter的事情了。需要定义一个Remember Me的Filter专门处理这个Cookie。值得一提的是,校验Cookie重新认证的过程还是要查数据库的,所以应该做到只有在必要的时候,即会话过期的时候,才执行校验操作。
8. Remember Me Filter与Login Filter的兼容
Login Filter所做的就是,让没有登录的用户,必须登录后才能处理请求。一般会直接返回错误码,让前端跳转到登录页,或者直接重定向到登录页。所以Remeber Me Filter肯定要放置在Login Filter之前。即会话过期后,先进行的应该是自动登录。
9. 登出后,Cookie的删除
用户执行登出操作后,肯定要删除浏览器的Cookie。否则,在Cookie过期之前,还是可以通过自动登录的方式,进入网站。但是,你不可能要求用户去操作浏览器,删除Cookie。这些操作应该由服务端完成。但是HTTP协议只有Set-Cookie的头,却没有类似Remove-Cookie这样的头。HttpServletResponse也没有明确的API可以删除客户端的Cookie。后来想到即可以通过添加不保存的同名Cookie来覆盖要删除的Cookie,后来参考了下Security的实现,发现它也是这么做的。代码如下:
public void logout(HttpServletRequest request, HttpServletResponse response) {
//利用覆盖的方法删除客户端的remember-me cookie
Cookie cookie = new Cookie("remember-me", (String)null);
cookie.setMaxAge(0);
response.addCookie(cookie);
request.getSession().invalidate();
}
【杂谈】Remember-Me的实现的更多相关文章
- 【转】PHP 杂谈《重构-改善既有代码的设计》之一 重新组织你的函数
原文地址: PHP 杂谈<重构-改善既有代码的设计>之一 重新组织你的函数 思维导图 点击下图,可以看大图. 介绍 我把我比较喜欢的和比较关注的地方写下来和大家分享.上次我写 ...
- 【管理心得之三十二】PMP杂谈---------爱情必胜术
这次一反常态,没有场景设计,我想借此文普及一下PMP是什么? 但我不知道这样枯燥的话题能否能引起你的兴趣,我不得不套用“标题党”<爱情必胜术>来博你眼球. 我真没有说谎,此文是献给那些孤身 ...
- [python爬虫] Selenium定向爬取海量精美图片及搜索引擎杂谈
我自认为这是自己写过博客中一篇比较优秀的文章,同时也是在深夜凌晨2点满怀着激情和愉悦之心完成的.首先通过这篇文章,你能学到以下几点: 1.可以了解Python简单爬取图片的一些思路和方法 ...
- 杂谈:HTML 5页面可视性API
译文来源:http://www.ido321.com/1126.html 原文:HTML5 Page Visibility API 译文:HTML 5的页面可视性API 译者:dwqs 在早期,浏览器 ...
- Ⅸ.spring的点点滴滴--IObjectFactory与IFactoryObject的杂谈
承接上文 ObjectFactory与IFactoryObject的杂谈 .net篇(环境为vs2012+Spring.Core.dll v1.31) public class parent { pu ...
- 子树大小平衡树(Size Balanced Tree,SBT)操作模板及杂谈
基础知识(包括但不限于:二叉查找树是啥,SBT又是啥反正又不能吃,平衡树怎么旋转,等等)在这里就不(lan)予(de)赘(duo)述(xie)了. 先贴代码(数组模拟): int seed; int ...
- 杂谈之SolrCloud这个坑货
杂谈之SolrCloud这个坑货 看<Solr In Action>时候看到对Solr不足的介绍有这么一段话:“One final limitation of Solr worth men ...
- 杂谈之不同行业的Solr
杂谈之不同行业的Solr 前几天去一家互联网创业公司面试搜索引擎开发工程师,结果被pass了,仍不住想来吐槽下.尽管当时面试没啥准备,也没表现好,但是也学到了不少东西.现在就随便吐槽一下吧. 本人是在 ...
- iOS APP安全杂谈
iOS APP安全杂谈 高小厨 · 2015/06/30 10:16 0x00 序 以前总是在这里看到各位大牛分享其安全渗透经验,而今我也很荣幸的收到了乌云的约稿,兴奋之情难以言表.由于IOS是一 ...
- WPF 杂谈——开篇简言。
这俩年多来笔者一直在从事关于WPF的开发.虽然不能说是专家级别的.但是对于WPF的应用还是有一定的了解.论他的灵活性决对不在WinForm之下.WPF的出现更是引发一段热议.他的何去何从更是让很多人感 ...
随机推荐
- Self Attention需要掌握的基本原理
字面意思理解,self attention就是计算句子中每个单词的重要程度. 1. Structure 通过流程图,我们可以看出,首先要对输入数据做Embedding 1. 在编码层,输入的word- ...
- jquery-能拖拽宽度的table
控件官方地址:http://www.bacubacu.com/colresizable/?utm_source=jquer.in&utm_medium=website&utm_camp ...
- go mysql insert变量到数据库
result, err1 := db.Exec("insert ignore into dish(name,calorie,confidence) values('"+str1+& ...
- 【深度学习】安装TensorFlow-GPU
1.Windows版 准备 干净的系统,没有安装过Python,有的话就卸载了. 另外我的系统安装了VS2015 VS2017(这里我不知道是不是必备的). 现在TensorFlow和cuda以及cu ...
- vscode 添加 includePath
使用vscode打开C项目时,vscode无法找到头文件路径,提示:configure includePath for better intellisense results 解决: 编辑~/.vsc ...
- 换PHP7后访问Apache虚拟站点Forbidden的问题解决
Httpd.conf中,注释掉前2行,补上后2行 <Directory /> #AllowOverride none #Require all denied Order deny,allo ...
- mysql--user表
mysql数据库 用例:mysql mysql> show tables; +---------------------------+ | Tables_in_mysql | +------- ...
- DataOutputStream and DataInputStream
1.在io包中,提供了两个与平台无关的数据操作流 数据输出流(DataOutputStream) 数据输入流(DataInputStream) 2.通常数据输出流会按照一定的格式将数据输出,再通过数据 ...
- map put值 使用匿名函数
List<Map<String, Object>> list = setRoleMenuRlMapper.selectMapByParams(params); // Map m ...
- 第64节:Java中的Spring Boot 2.0简介笔记
Java中的Spring Boot 2.0简介笔记 spring boot简介 依赖java8的运行环境 多模块项目 打包和运行 spring boot是由spring framework构建的,sp ...