【杂谈】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的出现更是引发一段热议.他的何去何从更是让很多人感 ...
随机推荐
- Effective Java -- 使可变性最小化
为了使类成为不可变的,应该遵循以下五条原则: 1. 不要提供任何会下盖对象状态的方法 2. 保证类不会被扩展 3. 使所有的域都是final的 4. 使所有的域都成为私有的 5. 确保对于任何可变组件 ...
- MySQL/Oracle索引的创建与使用
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 索引分单列索引和组合索引. 单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引 ...
- 线程中的队列(queue)
队列的类型和常用方法 队列是一种数据结构,它类似于列表.但列表是线程不安全的,而队列是线程安全的. python的queue(python3,python2为Queue)提供了3种队列: Queue: ...
- 【收藏】JS获取鼠标的X,Y坐标位置
JS的方法: <html> <head> <meta http-equiv="Content-Type" content="text/htm ...
- 关于http与https的注意点
背景:在一次项目生产上线中遇到地址在IOS版本的app中打不开或者接口请求不返回的情况,在安卓机和PC上表现正常,经排查,问题出在http请求上,原因详解 在早期PC上和安卓手机上比较不严格,在htt ...
- django2+python3+uwsgi+centos7部署网站
Centos7中安装Python虚拟环境 2018年08月27日 00:09:36 kaichenkai 阅读数:984 1.为什么要搭建虚拟环境? 问题:如果在一台电脑上, 想开发多个不同的项目, ...
- spring 装配
spring 3种装配方式: 支持混合配置:不管使用JavaConfig还是使用XML进行装配,通常都会创建一个根配置(root configuration), 这个配置会将两个或更多的装配类和/或X ...
- JavaScript(变量、作用域和内存问题)
JavaScript是一个变量松散型的语言.(不像Java一样强类型语言.) JavaScript变量包括两种:基本类型(简单的数据段)和引用类型(对象). 一.基本数据类型(5种) Undefine ...
- 在linux环境下用中文查询数据库
1.用SQL在linux环境下,查询语句的中文条件,查不到结果. mysql -h ***.***.***.*** -P 3303 -uroot -p*********** -D boztax -e ...
- 【Vue】谈Vue的依赖追踪系统 ——搞懂methods watch和compute的区别和联系
从作用机制和性质上看待methods,watch和computed的关系 图片标题[原创]:<他三个是啥子关系呢?> 首先要说,methods,watch和computed都是以函数为基础 ...