API设计:HTTP基本认证 vs API令牌

62

我目前正在为一个Web应用程序创建面向公共Web API的身份验证系统。考虑到每个用户帐户都有一个API密钥,并且每个请求都必须经过身份验证,我有两个选择:

  1. 使用HTTP基本身份验证,就像GitHub一样。

    请求必须发送到URL

    http://api.example.com/resource/id
    with basic authentication
    username: token
    password: the api key
    
  2. 以查询字符串参数形式传递API令牌。

    请求必须发送到该URL

  3. http://api.example.com/resource/id?token=api_key
    

还有第三种选项,就是在URI中传递令牌,但我个人不喜欢这种解决方案。

你会选择哪种解决方案?为什么?


那么使用令牌的 Cookie 怎么样?这是一个替代方案吗? - Arne Burmeister
11
不太对。API客户端通常是脚本,并且它们不支持cookies或会话。 - Simone Carletti
Github链接已失效。 - jakeorr
3
OP中的链接(“像GitHub一样”)并不是HTTP基本认证。 HTTP-BA规定认证信息必须在Authentication: 标头中传递。它也不安全:标头值是用户名和密码的简单、容易可逆的编码。它并不比明文发送用户名和密码更安全(编码仅仅是为了保护HTTP免受奇怪字符的影响)。 - jackr
1
@jackr 如果你使用HTTP,那么BA只有在你所声称的方式上才是不安全的。 - Zimano
4个回答

40

最好的选择可能是在标头中使用API密钥(例如,“Authorization: Token MY_API_KEY”),而不是作为URL参数:

相比HTTP基本身份验证的优点:

  • 更加方便,因为可以轻松地过期或重新生成令牌,而不影响用户的账户密码。
  • 如果遭到攻击,漏洞仅限于API,而非用户的主账户
  • 您可以在一个账户上拥有多个键(例如,用户可以并排拥有“测试”和“生产”密钥)。

相对于URL中的API密钥的优势:

  • 通过防止用户在URL中嵌入凭据来提供额外的安全措施。(此外,URL可能会出现在诸如服务器日志之类的东西中)

25
这个比较毫无意义。基本身份验证相当于将令牌放在头部。https://my_token:@api.example.com会导致头部出现Authorization: Basic [base64编码的令牌] - sandstrom
6
@ sandstrom,这可能在功能上等同于只是将用户名传递给基本身份验证,但重点是使用可刷新的令牌代替实际的帐户凭据,并且“授权:标记”使此过程明确。http://techblog.thescore.com/2014/06/25/http-basic-authentication-and-http-token-authentication/ - Yarin
在URL中使用API密钥是最高效的选项(完全没有降级)。 - mirekphd

18

我经常思考如何对API进行用户/请求身份验证,在比较了多种方案后,我最终选择使用亚马逊的解决方案,因为它不需要或不能使用OAuth。该解决方案基于签名机制,可以防止“中间人”问题,而基本身份验证和传递简单令牌会发送明文数据。是的,你可以添加SSL,但这会增加系统的复杂性...


16

我认为HTTP基本身份验证应该足够简单的需求。

在我看来,完整(且最终)的解决方案是实现一个OAuth提供者。 它不复杂,是一个简单的协议,并且可以给你很大的灵活性。 此外,它似乎是当前的趋势,因为许多大公司都在实施它,并且它得到了许多库的支持。


3
我认为针对这种服务,OAuth 过于复杂了。那么在这种情况下,你为什么要选择基本身份验证(Basic Auth)呢? - Simone Carletti
2
在编程方面,对我来说HTTP基本身份验证更加优雅。主要是因为它是标准的,没有人需要想出新的东西。 - Diego Giorgini
1
你能否解释一下HTTP基本认证相对于OAuth的限制? - elsurudo
23
上述列出的 URL 并非 https,而是普通的 http://,这是十分危险的。由于基本身份验证(Basic Auth)并不为这些凭据提供任何隐私保护,因此任何人都可以使用类似 Firesheep 的工具来获取 API 密钥和令牌。你应该在大多数 API 提供者(包括Github)使用的 https 上考虑使用基本身份验证。请注意,涉及敏感数据时,应始终使用更安全的身份验证方式。 - Tim Shadel
4
如果您需要向第三方(例如“代客停车钥匙”)发出授权,则需要OAuth,但我还没有看到许多API仅为客户端与服务端访问而实施OAuth。随着OAuth 2变得更加流行,这种情况可能会改变,但您仍然要求用户做更多的工作来建立连接。 - Yarin
3
使用HTTPS基本身份验证怎么样?这难道不比HTTP基本身份验证更安全吗?OAuth需要您发送几个请求才能获取令牌。 - kiedysktos

0

我更喜欢使用令牌解决方案。如果您没有实际用户拥有自己的用户名和密码,那么使用基本身份验证结构似乎不是按照预期使用。虽然这并不一定是错误的,但在我看来不够干净。它还消除了使用自定义标头的需要,我认为这使得双方的实现更加容易和清洁。我接下来要问的问题是,您是否应该使用双因素身份验证,或者是否需要管理会话。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接