当前位置:  开发笔记 > 编程语言 > 正文

RESTful身份验证

如何解决《RESTful身份验证》经验,为你挑选了11个好方法。

RESTful身份验证的含义是什么?它是如何工作的?我无法在Google上找到一个很好的概述.我唯一的理解是你在URL中传递会话密钥(remeberal),但这可能是非常错误的.



1> Arnaud Bouch..:

如何在RESTful客户端 - 服务器架构中处理身份验证是一个有争议的问题.

通常,可以通过以下方式在SOA over HTTP世界中实现:

通过HTTPS进行HTTP基本身份验证;

Cookie和会话管理;

HTTP标头中的令牌(例如OAuth 2.0 + JWT);

使用其他签名参数查询身份验证

您必须调整甚至更好地混合这些技术,以最好地匹配您的软件架构.

每种身份验证方案都有自己的PRO和CON,具体取决于安全策略和软件体系结构的用途.

通过HTTPS进行HTTP基本身份验证

大多数Web服务都使用基于标准HTTPS协议的第一个解决方案.

GET /spec.html HTTP/1.1
Host: www.example.org
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

它很容易实现,默认情况下在所有浏览器上都可用,但是有一些已知的缺点,比如浏览器上显示的糟糕的身份验证窗口,它会持续存在(这里没有类似LogOut的功能),一些服务器端额外的CPU消耗,以及将用户名和密码(通过HTTPS)传输到服务器的事实(在键盘输入期间让密码仅保留在客户端,并在服务器上存储为安全散列应该更安全) .

我们可能会使用摘要式身份验证,但它也需要HTTPS,因为它容易受到MiM或Replay攻击,并且特定于HTTP.

通过Cookies会话

说实话,在服务器上管理的会话并非真正无状态.

一种可能性是维护cookie内容中的所有数据.而且,在设计上,该cookie将被服务器端的处理(客户端,事实上,甚至不试图解释这个cookie数据:它只是手回服务器上的每个连续的要求).但是这个cookie数据是应用程序状态数据,因此客户端应该在纯粹的无状态世界中管理它,而不是服务器.

GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123

cookie技术本身是HTTP链接的,所以它不是真正的RESTful,它应该是独立于协议的,恕我直言.它易受MiM或Replay攻击.

通过令牌(OAuth2)授予

另一种方法是在HTTP标头中放置一个令牌,以便对请求进行身份验证.例如,这就是OAuth 2.0的功能.请参阅RFC 6749:

 GET /resource/1 HTTP/1.1
 Host: example.com
 Authorization: Bearer mF_9.B5f-4.1JqM

简而言之,这与cookie非常相似,并且遇到同样的问题:不是无状态,依赖于HTTP传输细节,并且受到许多安全漏洞的影响 - 包括MiM和Replay - 所以只能通过HTTPS使用.通常,JWT用作令牌.

查询验证

查询身份验证包括通过URI上的一些其他参数对每个RESTful请求进行签名.请参阅此参考文章.

它在本文中定义如下:

必须通过使用私有凭证作为签名标记对以小写字母顺序排序的查询参数进行签名来验证所有REST查询.应在URL编码查询字符串之前进行签名.

这种技术可能与无状态架构更兼容,也可以通过轻型会话管理(使用内存中会话而不是数据库持久性)来实现.

例如,以下是上面链接中的通用URI示例:

GET /object?apiKey=Qwerty2010

应该这样传播:

GET /object?timestamp=1261496500&apiKey=Qwerty2010&signature=abcdef0123456789

正在签名的字符串是/object?apikey=Qwerty2010×tamp=1261496500,并且签名是使用API​​密钥的私有组件的该字符串的SHA256哈希.

服务器端数据缓存始终可用.例如,在我们的框架中,我们在SQL级别而不是在URI级别缓存响应.因此,添加此额外参数不会破坏缓存机制.

有关基于JSON和REST的客户端 - 服务器ORM/SOA/MVC框架中的RESTful身份验证的一些详细信息,请参阅此文章.既然我们允许通信不仅通过HTTP/1.1,还命名管道或GDI消息(本地),我们试图实现一个真正的RESTful的认证模式,而不是依赖于HTTP特殊性(如头部或饼干).

稍后注意:在URI中添加签名可能被视为不良做法(因为例如它将出现在http服务器日志中),因此必须减轻它,例如通过适当的TTL来避免重放.但是,如果您的http日志遭到破坏,您肯定会遇到更大的安全问题.

在实践中,即将到来的OAuth 2.0的MAC令牌认证可能是关于"由令牌授予"当前方案的巨大改进.但这仍然是一项正在进行的工作,并且与HTTP传输有关.

结论

值得推断的是,REST不仅基于HTTP,即使在实践中,它也主要通过HTTP实现.REST可以使用其他通信层.因此,无论谷歌如何回答,RESTful身份验证都不仅仅是HTTP身份验证的同义词.它根本不应该使用HTTP机制,但应从通信层中抽象出来.如果您使用HTTP通信,由于Let's Encrypt计划,没有理由不使用正确的HTTPS,这是任何身份验证方案所必需的.


只有当服务器通过发回401 Unauthorized响应来请求HTTP授权时,才会出现丑陋的HTTP授权密码提示.如果你不喜欢它,只需发送403 Forbidden.错误页面可以包括登录方法或链接到它的方法.但是,反对cookie和http身份验证(无论状态是服务器端还是客户端)的最大争议是它们容易受到跨站点请求伪造的攻击.因此,最佳方法是自定义授权方案,自定义授权标头或自定义GET或POST参数.
如果您使用`Cookie`作为`HTTP Basic Auth`的更好替代品,您可以使用一种使身份验证失效和注销能力的方法进行真正的无状态身份验证.示例实现可以使用名为"Emulated-HTTP-Basic-Auth"的cookie,其具有与真实HTTP Basic Auth类似的值以及另外的set expire time.然后可以通过删除该cookie来实现注销.我猜想*任何能够支持HTTP Basic Auth的客户端也可以通过这种方式支持cookie身份验证.
我想正确答案是http://stackoverflow.com/questions/6068113/do-sessions-really-violate-restfulness
@MikkoRantalainen但是,正如我写的那样,这个cookie仍将由服务器管理.它是某种无国籍的,但不是"纯粹的"无国籍者.在所有情况下,您都需要专门用于客户端登录/注销的JavaScript代码,[完全可以使用HTTP Digest Auth](http://marcin-michalski.pl/2012/11/01/javascript-digest-authentication-restful -webservice-spring-security-javascript-ajax) - 好主意,但没有大的好处,在这里,重新发明轮子.
我会声称服务器实现了用于配置标头的UI和逻辑,但标头本身是无状态的.为API设计的客户端可以跳过使用服务器帮助来配置标头,并只传递类似于HTTP Basic Auth的所需信息.我的观点是,普通的UAs(浏览器)具有如此糟糕的Basic Auth实现,因此无法使用.可以使用服务器为另一个头(`Cookie`)中的相同内容提供仿真.

2> skrebbel..:

我怀疑那些热心地喊"HTTP身份验证"的人是否尝试过用REST创建一个基于浏览器的应用程序(而不是机器到机器的Web服务)(没有冒犯的意图 - 我只是觉得他们没有遇到过复杂的问题) .

我在RESTful服务上使用HTTP身份验证时发现的问题是生成可在浏览器中查看的HTML页面:

用户通常会得到一个丑陋的浏览器制作的登录框,这对用户不友好.你不能添加密码检索,帮助框等.

以不同的名称注销或登录是一个问题 - 浏览器将继续向站点发送身份验证信息,直到您关闭窗口

超时很难

铲球这些逐点非常有见地的文章是在这里,但是这导致了很多特定浏览器的JavaScript两轮牛车,变通办法变通办法,等等的.因此,它也不是向前兼容的,因此在发布新浏览器时需要不断维护.我不认为干净清晰的设计,而且我觉得这是一项额外的工作和头痛,所以我可以热情地向我的朋友展示我的REST徽章.

我相信cookie是解决方案.但等等,饼干是邪恶的,不是吗?不,他们不是,饼干经常使用的方式是邪恶的.Cookie本身只是一条客户端信息,就像浏览器在浏览时会跟踪的HTTP身份验证信息一样.这条客户端信息在每次请求时都会发送到服务器,就像HTTP身份验证信息一样.在概念上,唯一的区别是所述内容这块客户端状态中的可以由确定服务器作为其响应的一部分.

通过使用以下规则使会话成为RESTful资源:

一个会话映射一个关键用户ID(也可能是最后行动时间戳超时)

如果存在会话,则表示该密钥有效.

登录意味着POST到/ sessions,新密钥被设置为cookie

注销意味着删除/ sessions/{key}(使用重载的POST,记住,我们是浏览器,HTML 5还有很长的路要走)

通过在每个请求时将密钥作为cookie发送并检查会话是否存在且有效来完成身份验证

现在,与HTTP身份验证的唯一区别在于,身份验证密钥由服务器生成并发送给不断发送回来的客户端,而不是客户端从输入的凭据计算它.

converter42补充说,当使用https(我们应该)时,重要的是cookie将设置其安全标志,以便永远不会通过非安全连接发送身份验证信息.好极了,自己没见过.

我认为这是一个运行良好的充分解决方案,但我必须承认,我不足以识别此方案中的潜在漏洞 - 我所知道的是,数百个非RESTful Web应用程序使用的基本相同登录协议(PHP中的$ _SESSION,Java EE中的HttpSession等).cookie头内容仅用于寻址服务器端资源,就像接受语言可能用于访问翻译资源一样,等等.我觉得它是一样的,但也许其他人不一样?你们觉得怎么样?


哦,来吧,然后举个例子.那是什么其他方式,效果很好?我真的很想知道.HTTP Auth肯定不是,如果没有关闭浏览器就无法注销,如果没有大量特定于浏览器的非兼容JS,你就无法提供不错的登录UX.我并不在乎"纯粹的RESTful"与"几乎RESTful"以及整个相关的宗教辩论,但如果你说有几种方法,你应该把它们拼出来.
这是一个实用的答案,提出的解决方案是有效的.但是,在同一个句子中使用术语"RESTful"和"session"是错误的(除非中间也有"not";).换句话说:任何使用会话的Web服务都不是RESTful(根据定义).不要误解我的意思 - 你仍然可以使用这个解决方案(YMMV),但是术语"RESTful"不能用于它.我推荐O'Reilly关于REST的书,它非常易读并且深入地解释了这个主题.
@skrebbel:纯REST解决方案每次请求资源时都会发送身份验证数据,这不完美(HTTP Auth会这样做).建议的解决方案适用于大多数用例更好,但它不是RESTful.不需要战争,我也使用这个解决方案.我只是不声称它是RESTful.:)
使用真实世界用户代理(又名"浏览器")进行真正的RESTful身份验证,其中包含一个包含HTTP身份验证值的cookie.这样,服务器可以提供用于输入登录名和密码的UI,服务器可以强制注销(通过删除cookie).此外,在验证失败时,服务器必须使用临时重定向登录屏幕,而不是响应401以要求登录,并且在成功登录后使用临时重定向返回到先前位置.此外,服务器必须将登出操作(POST表单)嵌入到登录用户的几乎每个页面中.
我没有看到在同一个句子中使用"restful"和"session"没有任何问题,只要很清楚会话只存在于客户端.我不确定为什么会对这个概念做出如此重大的贡献.
@HaralanDobrev - 它只是一个更老的答案,所以它有更多的时间收集upvotes.也就是说,我不确定查询身份验证选项如何很好地映射到web*应用程序*.注意,我们在谈论浏览器在这里查看页面,而不是编程REST客户端与REST服务器通信.我没有完全解决这个问题,但我不确定我是否也希望身份验证令牌能够存放在我的浏览器历史记录中.
@johndodo这可能是,但你怎么建议进行身份验证?或者至少承认,创建一个RESTful的Web应用程序(应用程序,而不是服务!)根本不可能(根据您的严格定义).但你所援引的宗教书呆子战争没有实际用途.
我花了好几天在SO上阅读RESTful auth上的各种线程.我得出了一个类似的结论:不可能100%'RESTful'满足最严格的要求,并且浏览器访问安全的API(无论如何都没有openID).您可以代表用户拥有API的Web应用程序代理,但是您必须添加更多代码,这是为了在这种情况下不适用的理想而进行的混淆.即使在下面的查询签名中,也需要共享密钥.最好有一个会话而不是在一个cookie imo中存储一个秘密,你如何存储数据客户端?
HTTP Basic auth也可以通过javascript完成吗?所以你不一定需要坚持丑陋的浏览器框.考虑到这个答案来自'09,我正在考虑单页应用程序可能不公平,但您可以在客户端上执行基本身份验证存储凭据,并通过javascript将每个后续请求发送到标头中.

3> Kingz..:

这里的好人已经对这个主题说了足够的话.但这是我的2美分.

有两种互动模式:

    人机对话(HTM)

    机器对机器(MTM)

机器是公共分母,表示为REST API,演员/客户端是人或机器.

现在,在一个真正的RESTful架构中,无状态的概念意味着必须为每个请求提供所有相关的应用程序状态(意味着客户端状态).相关的是,REST API需要处理请求并提供适当的响应.

当我们在人机对应用环境中考虑这一点时,Skrebbel在上面指出的"基于浏览器",这意味着在浏览器中运行的(web)应用程序需要在每个请求中发送其状态和相关信息它使后端REST API.

考虑一下:您有一个REST API的数据/信息平台公开资产.也许您有一个处理所有数据立方体的自助BI平台.但是您希望您的(人类)客户通过(1)Web应用程序,(2)移动应用程序和(3)某些第三方应用程序访问此用户.最后,即使是MTM链也可以通向HTM - 对.因此,人类用户仍然处于信息链的顶端.

在前两种情况下,您有一个人机交互的案例,这个信息实际上是由人类用户消费的.在最后一种情况下,您有一个使用REST API的机器程序.

身份验证的概念适用于所有人.您将如何设计此类以便以统一,安全的方式访问REST API?我看到这个的方式,有两种方式:

方式1:

    首先没有登录.每个请求都执行登录

    客户端向每个请求发送其标识参数+请求特定参数

    REST API接受它们,转身,ping用户存储(无论是什么)并确认auth

    如果auth建立,请为请求提供服务; 否则,使用适当的HTTP状态代码拒绝

    对目录中所有REST API的每个请求重复上述操作

方法2:

    客户端以auth请求开始

    登录REST API将处理所有此类请求

    它接受auth参数(API密钥,uid/pwd或您选择的任何内容)并验证用户存储(LDAP,AD或MySQL DB等)的身份验证

    如果已验证,则创建一个身份验证令牌并将其交还给客户端/呼叫者

    然后,调用者将此auth令牌+请求特定参数与每个后续请求一起发送到其他业务REST API,直到注销或直到租约到期为止

显然,在Way-2中,REST API需要一种方法来识别和信任令牌有效.Login API执行了auth验证,因此目录中的其他REST API需要信任"valet密钥".

当然,这意味着需要在REST API之间存储和共享身份验证密钥/令牌.这个共享的,可信任的令牌存储库可以是本地/联合的,允许来自其他组织的REST API相互信任.

但我离题了.

关键是,需要维护和共享"状态"(关于客户端的身份验证状态),以便所有REST API都可以创建一个信任圈.如果我们不这样做,即Way-1,我们必须接受必须对进入的任何/所有请求执行认证行为.

执行身份验证是一个资源密集型过程.想象一下,针对每个传入请求,针对您的用户存储执行SQL查询以检查uid/pwd匹配.或者,加密并执行哈希匹配(AWS样式).从架构上讲,我怀疑每个REST API都需要使用常见的后端登录服务来执行此操作.因为,如果你不这样做,那么你到处乱丢auth代码.一团糟.

层次越多,延迟越多.

现在,采用Way-1并应用于HTM.如果您必须发送uid/pwd/hash或其他任何请求,您的(人类)用户是否真的关心?不,只要你不打扰她每秒抛出auth /登录页面.如果你这样做,祝客户好运.因此,您要做的是将登录信息存储在客户端的某个位置,在浏览器中,在开头,并在每次发出请求时发送.对于(人类)用户,她已经登录,并且"会话"可用.但实际上,她会根据每个请求进行身份验证.

与Way-2相同.您的(人类)用户永远不会注意到.所以没有伤害.

如果我们将Way-1应用于MTM怎么办?在这种情况下,由于它是一台机器,我们可以通过要求它提交每个请求的认证信息来解决这个问题.没人在乎!在MTM上执行Way-2不会引起任何特殊反应; 它是一台该死的机器.它可以少关心!

真的,问题是什么适合你的需要.无国籍状态需要付出代价.付出代价继续前进.如果你想成为一个纯粹主义者,那么也为此付出代价,继续前进.

最后,哲学并不重要.真正重要的是信息发现,演示和消费体验.如果人们喜欢你的API,你就完成了自己的工作.


我读了你的答案; 在您的解决方案中,对于通过用户点击在浏览器上发起的每个Web请求,都需要将"auth令牌"发送回用户单击正在调用的任何API.然后怎样呢?API执行对令牌的检查.反对什么?针对某种"令牌存储",它维护该令牌是否有效.你不同意那个"令牌商店"成为"国家"的守护者吗?真的,无论你如何看待这个,某个地方的某个人必须知道一些关于用户活动传递的"令牌".这就是国家信息所在的地方.
通过"无状态"服务,真正意味着特定服务器组件(CRUD API)不带任何状态.他们无法识别另一个用户,并在一次交易中完整地完成用户请求.那是无国籍的.但是某个地方的某个人必须坐下来判断这个用户是否有效.没有其他办法可以做到这一点; 密钥或密码或其他.从用户端传来的任何东西都必须经过身份验证和授权.
先生,您已经如此精美地解释了这一点,以至于我清楚地了解了手头的基本问题.你就像佛陀!我可以通过在传输层使用HTTPS来添加它,我们甚至可以阻止Man In the Middle攻击,这样就不会有人劫持我的标识符密钥(如果选择了Way-1)

4> jcoffland..:

这是一个真正完全RESTful的身份验证解决方案:

    在身份验证服务器上创建公钥/私钥对.

    将公钥分发给所有服务器.

    当客户端进行身份验证时:

    3.1.发出包含以下内容的令牌:

    到期时间

    用户名(可选)

    用户IP(可选)

    密码哈希(可选)

    3.2.使用私钥加密令牌.

    3.3.将加密的令牌发送回用户.

    当用户访问任何API时,他们还必须传递其身份验证令牌.

    服务器可以通过使用auth服务器的公钥解密来验证令牌是否有效.

这是无状态/ RESTful身份验证.

请注意,如果包含密码哈希,则用户还将发送未加密的密码以及身份验证令牌.服务器可以通过比较哈希来验证密码是否与用于创建身份验证令牌的密码匹配.使用HTTPS之类的安全连接是必要的.客户端的Javascript可以处理获取用户密码并将其存储在客户端,可以存储在内存中,也可以存储在cookie中,可能使用服务器的公钥进行加密.


如果某人掌握了该身份验证令牌并使用伪装成客户端来调用API,该怎么办?
@jcoffland你真的在这里提出你的答案(反复:-)但我不禁评论在每次通话时使用非对称加密的性能问题(计算强度).我只是看不到能够扩展的解决方案.查找HTTPS和SPDY协议.它保持连接打开的长度(HTTP保持活动,即状态),并通过同一连接(更多状态)批量服务多个资源,当然SSL本身仅使用非对称加密来交换对称密钥(也是州).
@Abidi,是的,这是一个问题.您可能需要密码.密码的哈希值可以包含在身份验证令牌中.如果有人能够窃取令牌,那么它将容易受到线下暴力攻击.如果选择了一个强大的密码短语就不会有问题.请注意,如果您使用https令牌盗窃,则需要攻击者首先获得对客户端计算机的访问权限.

5> arg20..:

说实话,我在这里看到了很好的答案,但是让我感到困扰的是当有人将整个无状态概念推向一个极端的教条时.它让我想起那些只想拥抱纯OO的老Smalltalk粉丝,如果某些东西不是一个对象,那么你做错了.给我一个休息时间.

RESTful方法应该让您的生活更轻松,减少会话的开销和成本,尝试遵循它,因为这是明智的做法,但是你遵循一个学科(任何学科/指南)到极端的那一刻不再提供预期的好处,那么你做错了.今天一些最好的语言同时具有函数式编程和面向对象.

如果您解决问题的最简单方法是将身份验证密钥存储在cookie中并在HTTP标头上发送,那么请执行此操作,只是不要滥用它.请记住,如果会话变得沉重而且很大,如果所有会话都包含一个包含密钥的短字符串,则会有什么大不了的事情?

我愿意接受评论中的更正,但我只是没有看到(到目前为止)让我们的生活变得悲惨的一点,只是避免在我们的服务器中保留一个大的哈希词典.


@AndréCaldas它不是REST,就像语言中的函数或原始类型不是oop一样.我不是说会议是可取的.我只是在遵循一系列做法的情况下发表意见,以至于他们不再向某人提供福利.(顺便说一句,请注意我并不反对你的言论,但是,我不会说它不是REST,我会说它不是*纯*REST).
---同意了!:-)
人们并没有试图禁止您使用会话。您可以自由地这样做。但是,如果这样做,则不是REST。

6> user2213684..:

首先,RESTful Web服务是STATELESS(或换句话说,SESSIONLESS).因此,RESTful服务没有也不应该包含会话或cookie的概念.在RESTful服务中进行身份验证或授权的方法是使用RFC 2616 HTTP规范中定义的HTTP Authorization标头.每个请求都应包含HTTP Authorization标头,并且请求应通过HTTP(SSL)连接发送.这是在HTTP RESTful Web服务中进行身份验证和验证请求授权的正确方法.我已经为Cisco Systems的Cisco PRIME Performance Manager应用程序实现了RESTful Web服务.作为该Web服务的一部分,我也实现了身份验证/授权.

鲁本斯戈麦斯.


从某种意义上说,每个请求本身都是有效的,没有先前请求的任何要求,因此它是无状态的.如何在服务器上实现这是另一回事,如果身份验证很昂贵,您可以执行一些缓存并在缓存未命中时重新进行身份验证.很少有服务器是完全无状态的,输出纯粹是输入的函数.它通常是对某个州的查询或更新.
HTTP身份验证仍然要求服务器跟踪用户ID和密码.这不是完全无国籍的.
不对.在这种情况下,您的所有请求都需要先前事务中的状态,即用户注册.我不明白为什么人们一直试图说服务器上存储的用户名和密码不是服务器端状态.看我的回答.
@jcoffland您是否了解计算密集型(因此资源密集型且速度极慢)非对称加密的深度程度如何?您所谈论的是一种在每个请求上都使用非对称加密的方案.HTTPS的最慢的方面,没有任何东西,是初始握手,其涉及创建公钥/私钥以非对称地加密共享秘密,随后用于对所有随后的通信进行对称加密.

7> Justin Sheeh..:

它肯定不是关于"会话密钥",因为它通常用于指代在REST的所有约束内执行的无会话身份验证.每个请求都是自我描述的,携带足够的信息来自行授权请求,而不需要任何服务器端应用程序状态.

解决此问题的最简单方法是从RFC 2617中的 HTTP内置身份验证机制开始.


我不认为在服务器上存储用户哈希密码应该被视为服务器端状态.用户是资源,包含名称,地址或散列密码等信息.
@jcoffland:两个账户都没有.首先,HTTP Auth不要求服务器存储密码.密码的*hash*代替存储(推荐使用8+轮的bcrypt).其次,服务器没有任何状态,因为每次请求都会发送授权标头.如果您将存储的密码哈希视为*state*,则它们不会比存储的公钥更多.

8> 小智..:

@skrebel(http://www.berenddeboer.net/rest/authentication.html)提到的"非常富有洞察力"的文章讨论了一种令人费解但却非常破碎的身份验证方法.

您可以尝试访问该页面(仅对经过身份验证的用户可以查看)http://www.berenddeboer.net/rest/site/authenticated.html,无需任何登录凭据.

(对不起,我无法对答案发表评论.)

我会说REST和身份验证根本不混合.REST意味着无状态,但"经过身份验证"是一种状态.你不能将它们放在同一层.如果你是一个RESTful的拥护者并对国家不满,那么你必须使用HTTPS(即将安全问题留给另一层).



9> Bjorn..:

我认为restful身份验证涉及将身份验证令牌作为参数传递给请求.例如api使用apikeys.我不相信使用cookies或http auth符合条件.



10> Saptarshi Ba..:

更新于201年2月16日

下面提到的方法实质上是OAuth2.0的 "资源所有者密码凭证"授权类型.这是一种简单的启动和运行方式.但是,通过这种方法,组织中的每个应用程序最终都会拥有自己的身份验证和授权机制.推荐的方法是"授权代码"授权类型.另外,在我之前的回答中,我推荐使用浏览器localStorage来存储身份验证令牌.但是,我开始相信cookie是用于此目的的正确选择.我在StackOverflow答案中详细说明了我的理由,授权代码授予类型实现方法,安全注意事项等.


我认为以下方法可用于REST服务身份验证:

    创建登录RESTful API以接受用于身份验证的用户名和密码.使用HTTP POST方法防止缓存和SSL在传输过程中的安全性成功验证后,API返回两个JWT - 一个访问令牌(更短的有效期,比如30分钟)和一个刷新令牌(更长的有效期,比如24小时)

    客户端(基于Web的UI)将JWT存储在本地存储中,并且在每个后续API调用中,在"授权:承载#access令牌"头中传递访问令牌

    API通过验证签名和到期日期来检查令牌的有效性.如果令牌有效,请检查用户(它将JWT中的"子"声明解释为用户名)是否可以通过缓存查找访问API.如果用户有权访问API,请执行业务逻辑

    如果令牌过期,则API返回HTTP响应代码400

    客户端在接收400/401时,使用"Authorization:Bearer #refresh token"标头中的刷新令牌调用另一个REST API以获取新的访问令牌.

    在使用刷新令牌接收呼叫时,通过检查签名和到期日期来检查刷新令牌是否有效.如果刷新令牌有效,则从DB刷新用户的访问权限缓存并返回新的访问令牌和刷新令牌.如果刷新令牌无效,则返回HTTP响应代码400

    如果返回新的访问令牌和刷新令牌,请转到步骤2.如果返回HTTP响应代码400,则客户端假定刷新令牌已过期并要求用户输入用户名和密码

    要注销,请清除本地存储

通过这种方法,我们每隔30分钟就会执行昂贵的加载缓存操作,其中包含用户特定的访问权限详细信息.因此,如果撤消访问权限或授予新访问权限,则需要30分钟才能反映或注销,然后登录.



11> 小智..:

这是做到这一点的方法:使用OAuth 2.0进行登录.

只要支持OAuth,您就可以使用Google以外的其他身份验证方法.


没有HTTPS,没有什么是安全的.
推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有