如何通过第三方 API 安全地维护用户身份验证? [英] How to securely maintain user authentication through a third party API?

查看:24
本文介绍了如何通过第三方 API 安全地维护用户身份验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个允许用户创建、编辑和保存文档的网络应用程序.用户帐户的数据库是单独控制的,我得到了一个 SOAP API,它会告诉我给定的用户名/密码是否有效.

I'm building a webapp that allows users to create, edit, and save documents. The database of user accounts is controlled separately and I've been provided a SOAP API that will tell me whether a given username/password is valid.

假设用户名/密码有效,API 将返回以下信息:
• 电子邮件地址
• 用户名
• login_number(帐户的唯一 ID,似乎是一个自增整数)

Assuming the username/password are valid, the API will give me back the following info:
• email address
• username
• login_number (unique id for the account, appears to be an auto-increment int)

我会将我的应用程序的数据存储在我自己的数据库中,因此我可能会使用 login_number 将数据绑定到各个用户.

I'll be storing data for my app in my own database so I'll probably be using the login_number to tie data to individual users.

我的问题是,一旦用户成功登录,我应该如何跟踪该用户.将 login_number 存储为 cookie 是可行的,但对我来说似乎非常不安全.我正在考虑类似于存储某种随机散列的 cookie 以及存储该散列和关联的 login_number 的查找表,但我不确定这是否足够.

My question is how I should keep track of a user once that user has successfully logged in. Storing the login_number as a cookie would work but seems like it'd be horribly insecure to me. I'm thinking something along the lines of a cookie storing some sort of random hash with a lookup table storing that hash and the associated login_number but I'm not really sure that's sufficient.

用 PHP/MySQL 标记,因为这是我计划使用的后端,但不确定它对这个问题是否真的很重要.

Tagged with PHP/MySQL as that's the back end I'm planning on working with, but not sure it really matters for this question.

推荐答案

这是任何开放式身份验证都非常常见的情况,例如 Facebook oAuth 2.0.一旦用户同意您的条款,Facebook 会提供他的用户名、电子邮件以及一种方式,您可以随时查看用户是否仍在登录.

This is very common case with any open authentication take Facebook oAuth 2.0 for example. Once user agrees on your terms, Facebook provides his userid, email and also a way to check, at any time when you want, whether the user is still logged-in or not.

所以,有几种方法:

  1. 依赖提供者:如果基于 User-Id,SOAP API 会提供用户是否登录的信息.您可以在执行任何需要身份验证的任务之前使用此调用.

  2. 在 SOAP API 之上构建您自己的身份验证:我猜这就是您打算做的事情.该方法是使用加密/散列且难以重新创建的令牌.
    想法是这样的

    (a)一旦用户登录,就创建一个唯一的令牌,将此令牌保存在用户的会话或某个永久存储中.可能在 memcache 或与 userId 映射的某个地方.基本上,无论您在哪里检索此令牌,您都知道与哪个用户相关联.

    (b) 将此令牌存储为 cookie.

    (c) 每当您想要进行身份验证,使用cookie中的token与保存在用户会话中的token进行匹配(或者拉出匹配token的userId,将当前userId与使用token拉取的userId进行匹配以进行验证).

    (d) 在注销时删除 cookie.

    现在,很有可能 中间人 附上这种方法.

    一种昂贵的方法是在每个请求结束时更改令牌.这并不能消除 MITM 攻击,但攻击的机会变得相当渺茫.
  1. Rely on the provider: If based on User-Id the SOAP API provides the information whether the user is logged in or not. You may just use this call before performing any task that require authentication.

  2. Build your own Authentication on top of SOAP API: This is what you are planning to do, I guess. The approach is to use a encrypted/hashed and hard-to-recreate token.
    The idea goes like this

    (a)As soon as user logs in create a unique token, save this token in user's session or some permanent store. May be in memcache or somewhere mapped with the userId. Basically, wherever you may retrieve this token, you know which user is associated with it.

    (b) Store this token as cookie.

    (c) Whenever you want to authenticate, use the token from cookie to match against the token saved in the user's session (or pull out the userId matching the token and match the current userId with userId pulled using token for validation).

    (d) delete cookie on logout.

    Now, there are good chance of man-in-the middle attach with this approach.

    One approach, and it's expensive, is that to change token at the end of each request. This does not eliminate MITM attack, but chances of attack gets fairly slim.

希望这会有所帮助.

Nonce Nonce 的概念很简单也很扎实.但我不确定它是否适用于您的情况.它基本上是为了保护 SOAP 调用.AWS 使用了类似的东西.

Nonce The idea of nonce is simple and very solid. But I am unsure it will be applicable to your case. It's basically to protect SOAP calls. AWS uses similar thing.

  1. 为客户端提供secretKey.
  2. 每当 cient 发出请求时,他都必须使用 secretKey(比如 token)和它用来创建的时间戳传递当前时间戳的哈希值令牌.
  3. 服务器通过将 token 与服务器创建的哈希值进行比较来验证 token数据库作为密码或密钥.
  4. 如果令牌匹配,则允许用户访问,否则不允许访问.
  5. 还有一件事,如果时间戳与服务器的当前时间戳相差太远,服务器也可能会禁止访问.
  1. Provide client with secretKey.
  2. Whenever cient makes a request, he has to pass a hash of current time-stamp with secretKey (say it token) and the timestamp that it has used to create the token.
  3. Server validates the token by comparing token with the hash that the server creates using timestamp passed in header and the secretKey stored else where on server-side, may be in database as password or secretKey.
  4. If the tokens match, user is allowed access else not.
  5. One more thing, the server may also disbar the access if timestamp is too off from server's current timestamp.

这种方法有效地免受 MITM 攻击,但不确定这是否最适合您.

This approach is effectively free from MITM attack, but not sure if this is best suited approach for you.

客户端服务器对话如下

client ----request timestamp                           --------> server 
       <---current timestamp                           -----------'
--- {ts: timestamp, token: Hash256(timestamp, secretKey)} --> isEqual(token, hash256(ts, secretKey))
                                                              |   |
                                        Access Denied<- false/   true --> ACCESS

@kramthegram 感谢提醒 Nonce

@kramthegram thanks for reminding Nonce

这篇关于如何通过第三方 API 安全地维护用户身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆