23

我一直在阅读有关该主题的很多内容,但我发现的只是过时或部分答案,这对我并没有太大帮助,实际上只是让我更加困惑。我正在编写一个由 Web 应用程序(托管在与 API 相同的域上)和 Android 应用程序访问的 Rest API(Node+Express+MongoDB)。

我希望 API 只能由我的应用程序和授权用户访问。我还希望用户能够仅使用他们的 Facebook 帐户注册和登录,并且我需要能够访问一些基本信息,例如姓名、个人资料图片和电子邮件。

我想到的一个可能的情况是:

  1. 用户使用 Facebook 登录 Web 应用程序,该应用程序被授予访问用户 Facebook 信息的权限并接收访问令牌。
  2. Web 应用程序要求 API 确认该用户确实在我们的系统上注册,发送电子邮件和 Facebook 收到的令牌。
  3. API 验证用户是否存在,将用户名、令牌和时间戳存储到 DB(或 Redis)中,然后返回到客户端应用程序。
  4. 每次客户端应用程序访问 API 端点之一时,它都必须提供用户名和令牌,而不是其他信息。
  5. API 每次都会验证提供的用户名/令牌对是否与存储在数据库中的最新用户名/令牌对匹配(使用时间戳进行排序),并且自我们存储这些信息以来不超过 1 小时(再次使用时间戳)。如果是这种情况,API 将处理请求,否则将发出 401 Unauthorized 响应。

这有意义吗?这种方法是否存在我遗漏的任何宏观安全漏洞?我看到使用 MongoDB 存储这些信息的一个问题是集合很快就会因旧令牌而变得臃肿。从这个意义上说,我认为最好使用具有 1 小时过期策略的 Redis,以便 Redis 自动删除旧信息。

4

1 回答 1

35

我认为更好的解决方案是:

  1. 通过 Facebook 登录
  2. 将 Facebook AccessToken 传递给服务器(通过 SSL 用于 android 应用程序,对于 Web 应用程序,只需在 FB 登录后将其重定向到 API 端点)
  3. 检查fb_access_token给定的,确保其有效。获取user_idemail并与现有用户交叉引用,看看它是新用户还是旧用户。
  4. 现在,创建一个随机的、单独api_access_token的,您将其返回给 webapp 和 android 应用程序。如果您需要 Facebook 进行登录以外的任何操作,请将其存储fb_access_token并在您的数据库中将其与新的api_access_token和您的user_id.
  5. 对于此后的每个呼叫,发送api_access_token以对其进行身份验证。如果您需要fb_access_token获取更多信息,可以通过从数据库中检索它来实现。

总结:只要有可能,避免通过fb_access_token. 如果api_access_token被入侵,您可以更好地控制查看攻击者是谁、他们在做什么等,而不是让他们掌握fb_access_token. 您还可以更好地控制设置过期日期、延长fb_access_tokens 等

只要确保每当您通过 HTTP 传递任何类型的 access_token 时,都使用 SSL。

于 2013-03-24T20:01:09.137 回答