为啥要记住我的令牌?
Posted
技术标签:
【中文标题】为啥要记住我的令牌?【英文标题】:Why remember me token?为什么要记住我的令牌? 【发布时间】:2011-07-15 22:43:31 【问题描述】:在为网站实现“记住我”功能时,为什么我们要把事情复杂化并且除了会话令牌之外还有一个称为记住我令牌的令牌。
据我所知,记住我令牌可用于登录和创建新会话令牌,而会话令牌仅持续几分钟或直到用户关闭浏览器。 为什么我们不能将会话令牌本身的到期时间延长到我们希望用户登录的所需时间?
我需要在运行在 tomcat 上的基于 flex 的应用程序中实现这样的功能,我想知道是否需要记住我的令牌
另外,是否可以在 tomcat 中直接使用此功能?
【问题讨论】:
【参考方案1】:因为根据定义,只要用户关闭浏览器,会话就会结束。因此,一旦浏览器关闭,会话 cookie 就会过期。
由于记住我功能的目的是让用户跨会话保持登录状态,因此记住我 cookie 中存储的信息必须在浏览器重新启动时保持不变。
要“开箱即用”地获得此功能,请查看使用框架 like Spring Security。
【讨论】:
如果我们在会话cookie中添加expires子句,那么它可以持续任意天数,那有什么坏处呢?编写具有两个不同令牌的复杂机制是否有任何具体原因?【参考方案2】:Remember-me cookie 通常存储用户名和某种令牌。它们都用于对用户进行身份验证。看看Improved Persistent Login Cookie Best Practice,描述的过程相当不错。
会话 cookie 用于在客户端存储会话 ID,它允许服务器识别会话并加载与会话关联的会话数据。
因此,记住我的 cookie 比会话 cookie 具有更长的生命周期(通常是几天或几周)。会话 cookie 通常会在几分钟后或浏览器关闭时过期。
在我看来,使用两种不同的 cookie 有几个原因:
如果只使用持久的记住我 cookie,服务器将需要对每个请求的用户进行身份验证。当使用额外的会话 cookie 时,只要会话有效,服务器就不必这样做。当然会话 ID 可以存储在记住我的 cookie 中,但这样做有什么意义呢? 从编码的角度来看,最好重用现有的会话机制。为什么要重新发明***,而不是仅仅添加一个可以轻松启用/禁用的功能(通过记住我的 cookie 进行身份验证)?【讨论】:
但我不明白为什么当我们需要更长的会话时不能延长会话 cookie 的寿命。我尝试添加一个 servlet 过滤器,该过滤器将 expire 子句添加到会话 cookie 中,从而增加其到期持续时间。我看不出使用这种对我来说非常方便的方法的危害,而不是构建一个全新的机制,在我的应用程序中引入一个记住我的 cookie。如果我添加了一个记住我的 cookie,那么我需要对我的应用程序进行一些更改 所以,我猜你没有在你的服务器上使用 Spring Security 甚至 BlazeDS、Spring Security 和 Spring BlazeDS Integration 的组合,是吗?这些可以提供开箱即用的记住我功能。如果您确实更改了会话 cookie 的到期日期,请不要忘记在服务器上配置会话超时。否则服务器可能会过早地使会话无效。 我只处于评估阶段,我有一个 blazeds 应用程序,我正在尝试实现身份验证。将过期时间添加到会话 cookie 似乎是一个简单的选择,而我不确定 spring security 是否可以轻松地与 blazeds 应用程序一起使用,包括它的 remember-me 功能 看看Spring BlazeDS Integration。最新版本增加了对 Spring Security 的记住我功能的支持。因此,它允许您使用 Spring Security 和 BlazeDS,并通过一些 Spring 配置,一切都应该开箱即用。【参考方案3】:1) 会话通常包含除用户登录名之外的一大堆数据。因此,如果您只是将过期日期设置为几周或几个月,就像记住我的令牌一样,您可能会因为成千上万的重量级会话对象而在服务器上遇到性能问题。
2) 记住令牌是客户端的,而不是服务器端的。这将所有存储要求放在用户的浏览器上,对于登录名等简单数据来说,这是一个更好的解决方案。如果您依赖会话 ID 链接到服务器上的内存对象,那么每次重新启动服务器或服务器进程(例如部署更新的应用程序)时,所有这些会话对象都会丢失。
【讨论】:
是否可以在不影响客户端代码的情况下将 Spring Security 无缝集成到您的 flex 应用程序中? 我不知道如何将我的 flex 应用程序集成到 Spring 安全性以使用其记住我功能,是否可以这样做。 我不知道,我不使用 Spring 或 Flex。【参考方案4】:人们正确地说会话包含许多重量级对象。当您的系统上有足够多的用户时,如果您尝试将他们全部保留在服务器拥有的有限内存中,最终您将在该内存最大值用完时使服务器崩溃。
我曾经参与过一个项目,其中生产代码更新出现内存泄漏。这是一个 J2EE 项目(是的 J2EE 不是 Java EE)。当用户在这家电话公司登录查看他们的发票时,用户会话没有从内存中正确释放(我不记得原因,但这绝对是问题所在)。这个错误模仿了你要故意做的事情。
服务器不断崩溃。所以我们在上面放了一个分析器。我们会观察内存使用量一整天都在上升,直到它在应用服务器崩溃后不久达到顶峰。我们添加了内存并增加了 VM 内存设置。我告诉他们这是内存泄漏,但由于我不是每小时 200.00 美元的“服务器专家”,人们不愿意相信它,因为在那里的人仍然相信垃圾收集器非常强大,而不是非常好。
两天后(它影响了“查看发票”系统,而不是主要业务系统,即它没有相同的工作负载或内存要求,即使它在服务器中有足够的硬件内存),他们聘请了一对每小时 200.00 美元的顾问在一天后告诉他们该应用程序存在上述内存泄漏。它已修复,一切都很好......减去顾问费。
无论如何,这里的要点是:如果您在用户注销或关闭浏览器(会话超时)时不结束用户会话,您将面临内存耗尽和服务器崩溃的真正风险.特别是如果您的网站或应用程序拥有大量用户。正如其他人所提到的,轻量级令牌/cookie 是最好的。
【讨论】:
【参考方案5】:我们应该使用 sessionId cookie 之外的另一个 cookie 来记住用户的原因不是因为会话应该很快过期,否则您将面临服务器上的性能问题。
Jetty(可能还有许多其他 servlet 容器)具有一项功能,可以将空闲会话从内存自动驱逐到磁盘或数据库,恕我直言,排除了上述所有关于将重量级会话存储在内存中的性能问题的理由。
使用另一个 cookie 的原因是,记住我是为了记住用户,即使在会话过期后也是如此。因此,如果用户的会话已过期,则使用另一个 cookie 对用户进行身份验证,而无需输入密码,这显然会降低网络钓鱼攻击的可能性。尽管它也有缺点,例如,如果有人访问您的笔记本电脑并窃取您的身份验证令牌,则可以冒充您,除非服务器应用更多安全措施将令牌绑定到您的客户端和位置。
简而言之,remember-me 是一种身份验证机制,而不是会话 cookie 的替代品。
我认为,只要将它们存储在内存之外,就可以设置长期会话到期日期。一旦它们过期,只需询问密码。许多网站提供此功能为“记住我 30 天”,仅通过使用长期 sessionId cookie 即可实现。
【讨论】:
以上是关于为啥要记住我的令牌?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Firefox 询问您是不是要记住非密码文本框的密码?