REST API身份验证


181

我正在构建一个将托管在服务器上的应用程序。我想为该应用程序构建一个API,以促进与任何平台(Web App,Mobile App)的交互。我不了解的是,在使用REST API时,我们如何验证用户身份。

例如,当用户登录后想要创建论坛主题时。我怎么知道该用户已经登录?


4
您可能应该在此处搜索“ REST身份验证”。其他许多问题也涵盖了它。
Brian Kelly

10
简而言之,让客户端使用HTTP Basic Auth(通过SSL!)向每个请求发送用户名和密码,或进行一次身份验证,以使客户端具有经过身份验证的会话,该会话将在不活动一段时间后过期(或者您选择覆盖您的Web框架的会话处理)。然后,可以将所述会话存储在cookie中,或者将其作为每个请求传递的参数(例如Java域中的JSESSIONID)。
opyate 2012年


从安全性角度来看,@ opyate在REST API情况下使用cookie处理会话并不是一个好主意,因为攻击者可以在未经用户同意的情况下发送请求。最好在HTTP标头(例如授权)中包含会话哈希或令牌。
s3v3n

1
@ s3v3n如果我错了,请纠正我,但是您和我的建议只是使用标头+本地存储组合来实现相同效果的不同方式。它是Authorization标头+例如浏览器localStorage VS Cookie标头+标准浏览器cookie存储。
opyate

Answers:


72

您可以使用HTTP基本或摘要身份验证。您可以在其顶部使用SSL来对用户进行安全身份验证,但是,这会稍微降低API的速度。

  • 基本身份验证-对用户名和密码使用Base64编码
  • 摘要式身份验证-在通过网络发送用户名和密码之前先对其进行哈希处理。

OAuth是最好的。oAuth提供的优势是可撤销或到期的令牌。请参阅以下有关如何实现的内容:注释中的工作链接:https : //www.ida.liu.se/~TDP024/labs/hmacarticle.pdf


4
请阅读此问题以及Les Hazelwood(Apache Shiro的作者)提供的答案。
justin.hughey 2014年

1
有用的链接Twitter如何保护其REST API:Twitter REST API安全性
-WildDev

由于这是公认的答案,因此我觉得必须提及您也可以使用摘要式身份验证,这一点很重要。阅读基本和数字认证这里的区别:stackoverflow.com/questions/9534602/...
Rayee Roded

116

例如,当用户登录时。现在假设用户要创建论坛主题,我如何知道该用户已经登录?

考虑一下-必须进行一些握手,告诉您的“创建论坛” API此当前请求来自经过身份验证的用户。由于REST API通常是无状态的,因此状态必须保留在某处。使用REST API的客户端负责维护该状态。通常,它以某种令牌的形式自用户登录以来就一直传递。如果令牌是好的,那么您的请求就是好的。

检查Amazon AWS如何进行身份验证。这是从一个API传递到另一个API的完美例子。

*我想在以前的回答中添加一些实际的答案。尝试使用Apache Shiro(或任何身份验证/授权库)。最重要的是,请尝试避免自定义编码。集成了您喜欢的库(我使用Apache Shiro,顺便说一句)之后,您可以执行以下操作:

  1. 创建一个登录/注销API,例如:/api/v1/loginapi/v1/logout
  2. 在这些登录和注销API中,对用户存储执行身份验证
  3. 结果是令牌(通常是JSESSIONID)被发送回客户端(网络,移动设备等)
  4. 从现在开始,您的客户随后进行的所有呼叫都将包含此令牌
  5. 假设您的下一个调用是调用一个名为 /api/v1/findUser
  6. 该API代码将要做的第一件事是检查令牌(“此用户是否已通过身份验证?”)
  7. 如果答案为否,那么您将向客户端返回HTTP 401状态。让他们来处理。
  8. 如果答案为是,则继续返回所请求的用户

就这样。希望这可以帮助。


所以,您所描述的实际上是会话cookie,对不对?
LordOfThePigs 2014年

是的,但是该会话在两个不同的位置“保持”。一个在API服务器中,另一个在浏览器中。成功登录后返回浏览器的JSON(或其他响应)应将API服务器上的会话ID传递回浏览器。这些会话由它们各自的代理独立管理。
金兹

11
我相信Kingz试图传达一种想法,即维持会议的机制是故意模糊的。会话cookie只是该机制的一种实现。
justin.hughey 2014年

2
@Kingz,该解决方案的安全性如何?例如,如果有任何黑客用session_id嗅探链接并开始发送内容正确的session_id的请求?我们可以通过在服务器连接中添加ssl来解决问题,但是客户端呢?
艾哈迈德·萨米洛

1
如何防止中间人跟踪会话被劫持?
m0z4rt

38
  1. 使用HTTP基本身份验证对客户端进行身份验证,但仅将用户名/密码视为临时会话令牌

    会话令牌只是附加到每个 HTTP请求的标头,例如:Authorization: Basic Ym9ic2Vzc2lvbjE6czNjcmV0

    上面的字符串Ym9ic2Vzc2lvbjE6czNjcmV0只是用Base64编码的字符串“ bobsession1:s3cret”(用户名/密码)。

  2. 要获取上面的临时会话令牌,请提供一个API函数(例如:),该函数http://mycompany.com/apiv1/login将master-username和master-password作为输入,在服务器端创建一个临时HTTP Basic Auth用户名/密码,并返回令牌(例如: Ym9ic2Vzc2lvbjE6czNjcmV0)。该用户名/密码应该是临时的,应在20分钟左右后过期。

  3. 为了提高安全性,请确保您的REST服务通过HTTPS提供服务,以使信息不会以纯文本格式传输

如果您使用的是Java,Spring Security库将为实现上述方法提供良好的支持


1
为什么它会在20分钟后过期?如果是在用户退出之前是登录的Facebook之类的网站怎么办?
Dejell 2015年

1
@dejel我当时假设“会话”本质上是临时的。如果用户闲置,它通常会过期
gerrytan

Base64的用途是什么?您可以只返回临时密码。在这两种情况下,真正重要的是此临时密码很强。检查security.stackexchange.com/a/19686/72945
e18r

7

我认为最好的方法是使用OAuth2。谷歌它,您会发现很多有用的帖子来帮助您进行设置。

从Web应用程序或移动应用程序为API开发客户端应用程序将变得更加容易。

希望对您有帮助。


2
请阅读此问题以及Les Hazelwood(Apache Shiro的作者)的答案。
justin.hughey 2014年

0

我一直在使用JWT身份验证。在我的应用程序中工作正常。

有一种身份验证方法将需要用户凭据。此方法将验证凭据并在成功的情况下返回访问令牌。

该令牌必须发送到请求标头中我的Web API中的所有其他方法。

它很容易实现,也很容易测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.