RESTful API:如何安全地存储承载API令牌?

时间:2015-05-22 19:14:48

标签: api rest github oauth token

我正在构建一个RESTful API。我唯一的问题是如何进行身份验证,因为我想要一种无状态方法,其中服务器所拥有的唯一信息就是请求本身。

所以我想我会看看大男孩们是怎么做到的。

我看到大多数服务都会向用户/应用程序发出令牌。然后在每个后续请求中使用它。例如,Twitter和GitHub使用OAuth2,我发现他们发出了持票令牌。到目前为止,这么好 - 无国籍,干净和简单:

$ curl -H"授权:令牌OAUTH-TOKEN" https://api.github.com/xyz

然而我有一个问题:我是否将OAUTH-TOKEN令牌存储在我的数据库中以验证用户......如果是,如何?

(编辑澄清问题)

让我们说这是我的数据库表:

用户|令牌
abc | 123个
xyz | 789

第一个用户想要使用其令牌发出API请求。所以他们知道他们的令牌是" 123"他们这样做:

卷曲-H"授权:承载123" https://myapi.com

这是我的API必须继续的所有信息,因此它会查找WHERE token =" 123",并找出它的用户" abc&#34 ;。简单。都好。回复了。

理想情况下,我希望我的表格像那样(简单,没有开销),所以我的问题确实是:将令牌存储在数据库中是不是一个坏主意

(我想这是因为我已经养成了因为处理正常的电子邮件/密码行而认为这很糟糕的习惯)

所以然后我想,好吧,让我们说需要在我的表中散列这些令牌:我怎么会查找行?这就是关于散列值查找的最后一个问题:我假设有可能发生冲突,因为如果两个令牌具有相同的散列,那么如果你根据散列值查找单独< / strong>你肯定不知道哪个用户提出了请求?

这让我了解了如何添加如何识别行的附加值。就像你需要一个电子邮件和一个密码来识别一行 - 而不仅仅是一个密码 - 我想知道API请求的等价物是什么。但是,是的,最简单的解决方案是最好的,我认为只需将它与令牌一起传递就可以很好地解决问题。

所以你真的已经回答了&#34;如果我确实需要存储令牌哈希&#34;我将如何识别该行?问题

剩下的唯一问题是&#34;我是否需要将它们存储在哈希 - 并产生这种开销?&#34;

1 个答案:

答案 0 :(得分:1)

我在这里看不到问题,所以我觉得我误解了你的问题。以下是我认为你在问的问题,请纠正我错在哪里:

  1. 您对身份验证的唯一要求是它是无状态的。具体来说,使用OAuth 是一项要求。
  2. 身份验证适用于您的 REST API。 API令牌不代表您的用户访问其他服务。
  3. 假设这是真的,那么您只需在auth标头中发送更多信息,而不仅仅是令牌。一个例子可能是:

    Authorization: MyScheme base64urlEncodedUserName.base64urlEncodedAccessToken
    

    这将允许您根据用户名执行查找。

    我也不明白为什么使用令牌作为键是一个问题,即使你存储它。只是哈希传入的令牌并根据哈希值执行查找?

    编辑:感谢您澄清问题,改进了下面的回复:

    在数据库中存储未访问的访问令牌是不是很糟糕?

    是和否。通过存储令牌而不是用户密码,您可以消除将他/她可能已经重用于多个站点的用户密码暴露给攻击者的危险。所以它绝对不像存储密码那么糟糕。

    但它可能仍然非常糟糕,取决于令牌授予访问权限的信息或操作类型 - 如果它是用于论坛软件之类的东西,那么它可能是好的。如果涉及信用卡信息,那肯定是坏事。

    问题基本上变成了:攻击者可以使用访问令牌做什么,他还不能做什么,攻击了数据库?如果使用令牌的唯一可用信息已存储在数据库中,并且不能使用令牌执行危险操作,则对令牌进行散列将获得极少的额外安全性。

    散列令牌会导致碰撞吗?

    这实际上提出了一个有趣的观点。很多人使用普通的哈希函数来哈希密码和盐。这可能会导致冲突,是的。但是如果你对你的令牌进行哈希处理,你应该使用加密哈希函数。在这种情况下,碰撞的可能性足够低(至少如果令牌足够长),它可能会被忽略。

    请参阅Why passwords should be hashedHow to safely store a password,了解加密哈希的一些不错的文章。