我正在构建一个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;
答案 0 :(得分:1)
我在这里看不到问题,所以我觉得我误解了你的问题。以下是我认为你在问的问题,请纠正我错在哪里:
假设这是真的,那么您只需在auth标头中发送更多信息,而不仅仅是令牌。一个例子可能是:
Authorization: MyScheme base64urlEncodedUserName.base64urlEncodedAccessToken
这将允许您根据用户名执行查找。
我也不明白为什么使用令牌作为键是一个问题,即使你存储它。只是哈希传入的令牌并根据哈希值执行查找?
编辑:感谢您澄清问题,改进了下面的回复:
是和否。通过存储令牌而不是用户密码,您可以消除将他/她可能已经重用于多个站点的用户密码暴露给攻击者的危险。所以它绝对不像存储密码那么糟糕。
但它可能仍然非常糟糕,取决于令牌授予访问权限的信息或操作类型 - 如果它是用于论坛软件之类的东西,那么它可能是好的。如果涉及信用卡信息,那肯定是坏事。
问题基本上变成了:攻击者可以使用访问令牌做什么,他还不能做什么,攻击了数据库?如果使用令牌的唯一可用信息已存储在数据库中,并且不能使用令牌执行危险操作,则对令牌进行散列将获得极少的额外安全性。
这实际上提出了一个有趣的观点。很多人使用普通的哈希函数来哈希密码和盐。这可能会导致冲突,是的。但是如果你对你的令牌进行哈希处理,你应该使用加密哈希函数。在这种情况下,碰撞的可能性足够低(至少如果令牌足够长),它可能会被忽略。
请参阅Why passwords should be hashed和How to safely store a password,了解加密哈希的一些不错的文章。