令牌认证和使用Cookie进行认证有何区别?
我正在尝试实现Ember Auth Rails Demo,但我不理解在Ember Auth FAQ中描述的为什么要使用令牌身份验证。
令牌认证和使用Cookie进行认证有何区别?
我正在尝试实现Ember Auth Rails Demo,但我不理解在Ember Auth FAQ中描述的为什么要使用令牌身份验证。
HTTP是无状态的。为了授权,您需要为您发送给服务器的每个请求“签名”。
令牌身份验证
向服务器发出的请求由“令牌”签名 - 通常意味着设置特定的HTTP标头,但是它们可以发送到HTTP请求的任何部分(POST正文等)
优点:
您只能授权希望授权的请求。(Cookies-即使是授权cookie也会发送到每个请求。)
免疫XSRF(XSRF的简短示例 - 我会通过电子邮件向您发送一个链接,看起来像<img src="http://bank.example?withdraw=1000&to=myself" />
,如果您通过cookie身份验证登录到bank.example
,且bank.example
没有任何XSRF保护措施,我将从您的帐户中提取资金,因为您的浏览器将触发对该URL的已经授权的GET请求。)请注意,您可以使用基于Cookie的身份验证采取防伪措施,但必须实现这些措施。
Cookies绑定到单个域。在域foo.example
上创建的cookie无法由域bar.example
读取,而您可以将令牌发送到任何您喜欢的域。这对于消耗多个需要授权的服务的单页应用程序特别有用-因此我可以在域myapp.example
上拥有Web应用程序,该应用程序可以向myservice1.example
和myservice2.example
发出经过授权的客户端请求。
缺点:
基于令牌的身份验证稍微容易遭受XSS攻击(例如,如果我能够在您的站点上运行注入脚本,我可以窃取您的令牌;但是基于cookie的身份验证也不是万无一失 - 虽然标记为http-only的cookie无法被客户端读取,但客户端仍然可以代表您发出请求,这些请求将自动包括授权cookie。)
要下载文件的请求,只能由授权用户使用,需要使用File API。对于基于cookie的身份验证,同一请求可以“开箱即用”。
cookie身份验证
总体而言,我认为令牌会给你更好的灵活性(因为你不受单个域名的限制)。缺点是你需要做相当多的编程工作。
针对谷歌员工:
状态性
机制
Authorization
,只是普通的头部,没有特殊处理,客户端必须管理传输的所有方面状态性比较
hash(data+秘钥)
生成的签名一起存储,其中秘钥只有服务器知道,因此可以验证令牌数据的完整性机制比较
httpOnly
,从而防止客户端JavaScript访问总结
令牌需要存储在某个地方(本地/会话存储或cookie中)
令牌可以像cookie一样过期,但您有更多的控制权
本地/会话存储无法跨域工作,请使用标记cookie
每个CORS请求都将发送预检请求
当您需要流式传输数据时,请使用令牌来获取签名请求
处理XSS比处理XSRF更容易
令牌会发送到每个请求中,请注意其大小
如果存储机密信息,请加密令牌
JSON Web Tokens可用于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/
我认为这里有一些混淆。基于cookie的身份验证和现在使用的HTML5 Web存储的重要区别是,浏览器被构建为每当它们从设置了cookie的域请求资源时发送cookie数据。除非关闭cookie,否则无法阻止它。浏览器不会发送Web Storage中的数据,除非页面中的代码发送它。而且页面只能访问它们存储的数据,而不能访问其他页面存储的数据。
因此,一个担心他们的cookie数据可能被Google或Facebook使用的用户可能会关闭cookie。但是,除非广告商找到了利用它的方法,否则他们没有关掉Web Storage的理由。
所以,基于cookie的身份验证与基于令牌的身份验证之间的区别就在于后者使用了Web Storage。
基于令牌的身份验证是无状态的,服务器不需要在会话中存储用户信息。这使得应用程序能够扩展而不必担心用户登录的位置。虽然基于cookie的Web服务器框架亲和力较强,但这对基于令牌的身份验证并不是问题。因此,可以使用相同的令牌从已登录的域以外获取安全资源,避免了另一个uid/pwd身份验证。
这里有一篇非常好的文章:
使用令牌(Token)的情况包括:
需要联合验证时。例如,您想要使用一个提供程序(Token Dispensor)作为令牌发行者,并将您的API服务器用作令牌验证器。应用程序可以通过Token Dispensor进行身份验证,接收一个令牌,然后将该令牌呈现给您的API服务器进行验证。(同样适用于Google登录、Paypal、Salesforce.com等)。
需要异步处理时。例如,您希望客户端发送请求,然后将该请求存储在某个地方,以便由另一个系统“稍后”执行。该分离的系统将不会与客户端有同步连接,也可能没有直接连接到中央令牌提供机构。JWT可以被异步处理系统读取,以确定是否可以和应该在稍后的时间完成工作项。这在某种程度上与上述联合验证思想有关。但请注意: JWT有过期时间。如果保存工作项的队列在JWT生命周期内未被处理,则不再信任声明。
需要客户端签名请求时。在此情况下,请求是由客户端使用私钥签署的,服务器将使用客户端已注册的公钥进行验证。
主要区别之一是cookie受到同源策略的限制,而令牌则不受。这会产生各种下游影响。
由于cookie只发送到特定主机并从特定主机接收,因此该主机必须承担验证用户的负担,并且用户必须在该主机上创建带有安全数据的帐户以进行验证。
另一方面,令牌是由发行者发放的,不受同源策略的限制。发行者可以是任何人,由主机决定信任哪些发行者。像Google和Facebook这样的发行者通常很值得信赖,因此主机可以将验证用户(包括存储所有用户安全数据)的负担转移到另一方,并且用户可以将其个人数据整合到特定发行者下,而不必为与每个主机交互时记住一堆不同的密码。
这允许单点登录场景降低用户体验中的总体摩擦。理论上,随着专门的身份提供者涌现来提供认证服务,网络也变得更加安全,而不是让每个网站都自己开发可能不完善的认证系统。随着这些提供者的出现,即使对于非常基本的资源,提供安全的Web资源的成本也趋近于零。
因此,总的来说,令牌减少了提供身份验证所涉及的摩擦和成本,并将安全Web的各个方面的负担转移到更能够实施和维护安全系统的集中化方。
会话 cookie 需要您与存储您登录状态的另一端数据库共享个人密钥。这里没有任何花哨的东西,只是一个密码短语来标识您的会话,但细节可能有所不同。
身份验证令牌使用复杂的加密技术,消除了需要存储您登录状态的数据库的需求,通过发出一份文件并在指定提供者的签名下发布允许您进行的操作及其截止日期。
打个比喻,cookie 就像会员卡,接待员需要打电话或查询数据库以检查您是否是会员。而身份验证令牌就像带有签名和过期日期的支票。安全性基于签名的假设,即很难伪造,而无需直接向发行方询问。
在两种情况下,都涉及授权,而非认证。拥有会员卡或支票的任何人都拥有访问权,他们不能证明您的身份,只是证明您有权访问所请求的资源。因此,它们必须小心防范盗窃,特别是对于难以撤销的身份验证令牌更是如此。
JWT vs Cookie Auth
| | Cookie | JWT |
| Stateless | No | Yes |
| Cross domain usage | No | Yes |
| Mobile ready | No | Yes |
| Performance | Low | High (no need in request to DB) |
| Add to request | Automatically | Manually (if not in cookie) |