令牌认证与Cookie

时间:2013-06-08 15:07:11

标签: authentication cookies ember.js

使用Cookie进行令牌身份验证和身份验证之间有什么区别?

我正在尝试实现Ember Auth Rails Demo,但我不明白使用令牌身份验证背后的原因,如Ember Auth FAQ中有关“为什么是令牌身份验证?”的问题所述。

8 个答案:

答案 0 :(得分:236)

Http是无国籍的。为了授权你,你必须签署"您发送到服务器的每一个请求。

令牌身份验证

  • 对服务器的请求由"令牌" - 通常它意味着设置特定的http标头,但是,它们可以在http请求的任何部分发送(POST正文等)

  • 优点:

    • 您只能授权您要授权的请求。 (Cookies - 甚至为每个请求发送授权cookie。)
    • 免疫XSRF(XSRF的简短示例 - 我会在电子邮件中向您发送一个类似<img src="http://bank.com?withdraw=1000&to=myself" />的链接,如果您通过cookie身份验证登录到bank.com,并且bank.com没有任何XSRF保护手段,我会通过您的浏览器触发对该网址的授权GET请求来从您的帐户中提取资金。)注意防伪措施您可以使用基于cookie的身份验证 - 但您必须实现这些。
    • Cookie绑定到单个域。域名bar.com上无法读取域foo.com上创建的cookie,您可以将令牌发送到您喜欢的任何域。这对于使用需要授权的多个服务的单页应用程序特别有用 - 因此我可以在myapp.com域上拥有一个可以向myservice1.com和myservice2.com发出授权客户端请求的Web应用程序。 / LI>
  • 缺点:
    • 您必须将令牌存储在某处;而cookie则存储在开箱即用的状态#34;想到的位置是localStorage(con:即使关闭浏览器窗口后令牌仍然存在),sessionStorage(pro:关闭浏览器窗口后丢弃令牌,con:在新选项卡中打开链接将呈现该选项卡)匿名)和cookies(专业版:关闭浏览器窗口后,令牌将被丢弃。如果您使用会话cookie,则在新标签页中打开链接时将对您进行身份验证,并且您可以免除XSRF,因为您&#39 ;重新忽略用于身份验证的Cookie,您只需将其用作令牌存储.Con:Cookie会针对每个请求发送。如果此Cookie未标记为仅https,则您向人员开放中间的攻击。)
    • 对基于令牌的身份验证进行XSS攻击会稍微容易一些(即如果我能够在您的网站上运行注入的脚本,我可以窃取您的令牌;但是,基于cookie的身份验证也不是银弹 - 虽然客户无法读取标记为仅限http的cookie,但客户仍可代表您提出自动包含授权Cookie的请求。)
    • 下载文件的请求(仅适用于授权用户)要求您使用File API。相同的请求开箱即用,可用于基于cookie的身份验证。

Cookie身份验证

  • 对服务器的请求始终由授权cookie登录。
  • 优点:
    • Cookie可以标记为&#34; http-only&#34;这使得他们无法在客户端阅读。这对于XSS攻击保护更好。
    • 开箱即用 - 您不必在客户端实施任何代码。
  • 缺点:
    • 绑定到单个域。 (因此,如果您有一个单页应用程序向多个服务发出请求,您最终可能会像反向代理一样做疯狂的事情。)
    • 易受XSRF攻击。您必须实施额外措施,以防止跨站点请求伪造您的站点。
    • 针对每个请求发送(即使是不需要身份验证的请求)。

总的来说,我说令牌会给你更好的灵活性,(因为你不会受到单一域名的束缚)。缺点是你必须自己做一些编码。

答案 1 :(得分:31)

  • 代币需要存储在某处(本地/会话存储或cookie)

  • 令牌可以像Cookie一样过期,但您有更多控制权

  • 本地/会话存储无法跨域工作,使用标记Cookie

  • 将在每个CORS请求上发送预检请求

  • 当您需要流式传输内容时,请使用令牌获取已签名的请求

  • 与XSRF相比,处理XSS更容易

  • 每次请求都会发送令牌,请注意其大小

  • 如果您存储机密信息,请加密令牌

  • JSON Web令牌可以在OAuth中使用

  • 代币不是银子弹,请仔细考虑您的授权用例

http://blog.auth0.com/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies/

http://blog.auth0.com/2014/01/07/angularjs-authentication-with-cookies-vs-token/

答案 2 :(得分:26)

典型的网络应用主要是无状态,因为它具有请求/响应性质。 HTTP协议是无状态协议的最佳示例。但由于大多数网络应用需要状态,为了在服务器和客户端之间保持状态,使用cookie使服务器可以将每个响应发送回客户端。这意味着从客户端发出的下一个请求将包含此cookie,因此将被服务器识别。通过这种方式,服务器可以与无状态客户端保持会话,主要了解应用的状态的所有内容,但存储在服务器中。在这种情况下,客户端决不会持有状态,这不是Ember.js的工作方式。

在Ember.js中,情况有所不同。 Ember.js使程序员的工作变得更容易,因为它确实为您提供了状态,在客户端,每时每刻都知道它的状态,而无需向服务器要求数据。

但是,在客户端中持有状态有时也会引入在无状态情况下根本不存在的并发问题。然而,Ember.js也为您解决了这个问题,特别是ember-data就是为此而构建的。总之,Ember.js是为有状态客户设计的框架。

Ember.js不像典型的无状态网络应用,其中会话和相应的Cookie几乎完全处理由服务器。 Ember.js完全在javascript中保存它的状态(在客户端的内存中,而不像其他一些框架那样在DOM中),并且不需要服务器来管理会话。这导致Ember.js在许多情况下更加通用,例如当您的应用处于离线模式时。

显然出于安全原因,每次发出请求时都需要将某种令牌唯一键发送到服务器才能进行身份验证,这样服务器可以查找发送令牌(最初由服务器发出),并在将响应发送回客户端之前验证它是否有效。

在我看来,Ember Auth FAQ中所述使用身份验证令牌而不是cookie的主要原因主要是因为Ember.js框架的性质,也因为它更符合有状态的网络应用范例。因此,在构建Ember.js应用程序时,cookie机制不是最佳方法。

我希望我的回答会给你的问题带来更多意义。

答案 3 :(得分:8)

我认为这里有一些混乱。基于cookie的身份验证与HTML5 Web Storage现在可用的身份验证之间的显着差异在于,浏览器构建为在从设置它们的域请求资源时发送cookie数据。如果不关闭cookie,你无法阻止它。浏览器不会从Web存储发送数据,除非页面中的代码发送。页面只能访问他们存储的数据,而不能访问其他页面存储的数据。

因此,用户担心谷歌或Facebook可能会使用他们的cookie数据的方式可能会关闭cookie。但是,他们没有理由关闭Web存储(直到广告商想出一种方式来使用它)。

因此,这是基于cookie和基于令牌的区别,后者使用Web存储。

答案 4 :(得分:4)

基于令牌的身份验证是无状态的,服务器无需在会话中存储用户信息。这使得能够扩展应用程序而无需担心用户登录的位置。基于cookie的Web服务器框架关联性虽然不是基于令牌的问题。因此,相同的令牌可用于从我们登录的域之外的域中获取安全资源,这避免了另一个uid / pwd身份验证。

非常好的文章:

http://www.toptal.com/web/cookie-free-authentication-with-json-web-tokens-an-example-in-laravel-and-angularjs

答案 5 :(得分:1)

主要区别之一是cookie受制于同源起源策略,而令牌则不受制。这会产生各种下游效果。

由于cookie仅与特定主机之间来回发送,因此主机必须承担验证用户身份的负担,并且用户必须在该主机上创建具有安全性数据的帐户,才能进行验证。

另一方面,

令牌已发行,并且不受同一来源政策的约束。发行者实际上可以是任何人,由主持人决定信任哪些发行者。像Google和Facebook这样的发行人通常受到高度信任,因此主机可以将验证用户身份的负担(包括存储所有用户安全数据)转移到另一方,并且用户可以将其个人数据合并到特定发行人下,而不必记住与之交互的每个主机都使用了不同的密码。

这允许单点登录方案减少用户体验中的整体摩擦。从理论上讲,随着专门的身份提供者出现以提供身份验证服务,而不是让每个主要网站都旋转自己的,可能是半熟的身份验证系统,网络也变得更加安全。随着这些提供商的出现,为非常基本的资源趋势提供安全的Web资源的成本也趋于零。

因此,一般而言,令牌可以减少与提供身份验证相关的摩擦并降低成本,并将安全Web各个方面的负担转移给能够更好地实施和维护安全系统的集中各方。

答案 6 :(得分:1)

在...时使用令牌

需要联邦。例如,您要使用一个提供程序(令牌Dsipensor)作为令牌发行者,然后将您的api服务器用作令牌验证器。应用可以向令牌分发器进行身份验证,接收令牌,然后将该令牌提供给您的api服务器以进行验证。 (同样适用于Google登录,Paypal或Salesforce.com等)

需要异步。例如,您希望客户端发送一个请求,然后将该请求存储在某个地方,以便由单独的系统“稍后”执行。该单独的系统将没有与客户端的同步连接,并且可能没有与中央令牌分配器的直接连接。异步处理系统可以读取JWT,以确定该工作项是否可以并且应该在以后的时间完成。在某种程度上,这与上面的联合会想法有关。不过请注意:JWT到期。如果保存工作项的队列在JWT的生存期内未得到处理,则声明将不再受信任。

需要签名签名的请求。在此,请求由客户端使用其私钥签名,服务器将使用客户端已注册的公钥进行验证。

答案 7 :(得分:0)

对于Google员工

  • 请勿将状态性状态传输机制
  • 混合使用

状态

  • 有状态 =将授权信息保存在服务器端,这是传统方式
  • 无状态 =将授权信息与签名一起保存在客户端,以确保完整性

机制

  • Cookie =一种特殊的标头,具有浏览器的特殊处理(访问,存储,有效期,安全性,自动传输)
  • 自定义标题 =例如Authorization只是标头,没有任何特殊处理,客户必须管理转移的各个方面
  • 其他。可以利用其他传输机制,例如查询字符串是转移身份验证一段时间的一种选择,但由于其不安全性而被放弃

状态比较

  • “状态授权”是指服务器在服务器上存储和维护用户授权信息,使授权成为应用程序状态的一部分
  • 这意味着客户端只需要保留一个“身份验证ID”,服务器就可以从其数据库中读取身份验证详细信息
  • 这意味着服务器保留一个活动身份验证池(已登录的用户),并将针对每个请求查询此信息
  • “无状态授权”表示服务器不存储和维护用户身份验证信息,它根本不知道哪些用户已登录,并依靠客户端生成身份验证信息
  • 客户端将存储完整的身份验证信息,例如您的身份(用户ID),以及可能的权限,到期时间等,这不只是身份验证ID,因此,它被赋予了新的名称令牌 >
  • 客户端显然不可信任,因此将身份验证数据与从hash(data + secret key)生成的签名一起存储,在签名中,只有服务器才知道秘密密钥,因此可以验证令牌数据的完整性
  • 请注意,令牌机制仅能确保完整性,而不能保证机密性,客户端必须实现这一点
  • 这还意味着对于每个请求客户端,必须提交一个完整的令牌,这会产生额外的带宽

机制比较

  • “ Cookie”只是标题,但在浏览器上有一些预加载的操作
  • Cookie可以由服务器设置并由客户端自动保存,并将自动发送到相同的域
  • 可以将Cookie标记为httpOnly,从而阻止客户端JavaScript访问
  • 预加载的操作可能无法在浏览器以外的平台(例如移动设备)上使用,这可能会导致额外的工作量
  • “自定义标头”只是没有预加载操作的自定义标头
  • 客户负责接收,存储,保护,提交和更新每个请求的自定义标头部分,这可能有助于防止某些简单的恶意URL嵌入

总结

  • 没有魔术,身份验证状态必须存储在服务器或客户端的某个位置
  • 您可以使用Cookie或其他自定义标头实现有状态/无状态
  • 当人们谈论这些事情时,他们的默认思维方式主要是:无状态=令牌+自定义标头,有状态=身份验证ID + Cookie;这些不是唯一可能的选择
  • 它们各有利弊,但即使是加密令牌,也不应存储敏感信息