【问题标题】:Secure API for iOS without user account无需用户帐户的 iOS 安全 API
【发布时间】:2013-01-05 07:18:27
【问题描述】:

我知道这是一种很受欢迎的问题,但我找不到任何其他可以满足我特定需求的问题。

背景

  • 我有一个 iOS 应用程序,它从我的 Ruby on Rails 开发的 Web API 中检索数据。
  • 我想将我的 API 私有化,以便其他来源无法使用来自我的 API 的数据(即,其他人开发了一个应用程序,该应用程序访问了我的 API 网址并将数据用于他们的客户)

要求

  • (硬)私有 API,以便只有授权客户端(仅来自 iOS 应用程序)才能访问 API 中的数据。
  • (困难)用户不必创建用户/密码帐户。
  • (SOFT) 我读到 SSL 在尝试获得 Apple 批准的应用程序时可能会成为一场噩梦。由于这是一个小型应用程序(截至目前),我更愿意依赖 SSL。 但是,如果您能指出我在 iOS 上使用 SSL 处理所有 API 流量轻松的正确方向,我会全力以赴)。

如果您失去兴趣,请跳到问题的最后 :)

到目前为止的想法

想法 1:

  1. iOS 从 Web 请求令牌,发送一些 UUID
  2. WEB 响应 API_Token 和 Token_Expiry
  3. WEB 将 UUID、API_Token 和 Token_Expiry 存储在数据库中
  4. iOS 将 API_Token、Token_Expiry 存储在本地
  5. iOS 通过发送 UUID 和 API_Token 请求数据
  6. WEB 验证 UUID 和 API_Token,响应数据
  7. 重复步骤 5-6 直到 API_Token 过期,然后从步骤 1 开始重复

*想法2:(单次使用API​​_Token)*

  1. iOS 从 Web 请求令牌,发送一些 UUID
  2. WEB 使用 API_Token 响应
  3. WEB 将 UUID 和 API_Token 存储在数据库中
  4. iOS 将 API_Token 存储在本地
  5. iOS 通过发送 UUID 和 API_Token 请求数据
  6. WEB 验证 UUID 和 API_Token,以数据和新令牌响应
  7. iOS 获取数据并在本地保存 NEW TOKEN
  8. 无限期地重复步骤 5-7

这些想法的问题

我相信 iOS 不再有完美的 UUID 解决方案。如果 UUID 可以随时间变化(或者如果用户有多个 iOS 设备),则可能会出现身份验证问题。

如果黑客获得 API 密钥,我不希望他们能够访问数据(因此产生了过期或新令牌的想法)。

问题

对于在 Rails 和 iOS 之间创建安全 API,您有什么建议?


编辑 1:

我仍然很惊讶这不是一直出现的事情。必须有大量的应用程序与 API 通信,但不强制用户注册。如果 SSL 或 OAuth 是唯一的正确解决方案,请辩护。我全神贯注。

【问题讨论】:

  • AFAIK,如果没有一些容易出错的 iCloud 杂技,就无法跨设备跟踪用户,有人可能会纠正我。至于保护您的 API,请使用长令牌挑战客户端并让它返回由秘密函数生成的哈希。不完美,但也许足够好。
  • @s.bandara 因为我对以这种方式保护事物非常陌生,您能否指出我可以跟进或进一步解释的链接?如果我挑战每个客户端(我的 iOS 应用程序),我是否需要通过 1. 请求数据、获取令牌、发送哈希、然后获取数据(4 次)来“打开通信线路”?

标签: ios objective-c ruby-on-rails api


【解决方案1】:

除了跨设备跟踪用户的问题,我不知道如何提供一个相当简单和可靠的机制,除了一个游戏中心帐户,让我们讨论一个简单的方法来关闭你的 API 到其他应用程序。

握手将涉及您的客户端提交一个 URL 请求,该请求可能已经包含一个特定于设备的令牌来识别您的用户。来自您的服务器的响应将是字符串形式的随机一次性质询。客户端和服务器都知道一个重要的函数,它生成一个响应字符串作为挑战的函数,可能还有用户令牌,从而验证客户端。

该机制绝不安全,但实施起来很简单,并且会给其他人提供一些障碍。您绝对应该验证用户令牌的形式以获得额外的保护。例如,如果您的令牌是 MAC 地址,则请求必须采用 MAC 地址的形式。

【讨论】:

  • 感谢您的评论和回答。我写了自己的答案,但 +1 让你加入讨论。每次我读到有关该主题的内容时,它都会引起共鸣并以某种方式在某处被使用。因此,非常感谢您的回答。
【解决方案2】:

我最终根据在网上找到的一些建议推出了自己的解决方案(请参阅最后的参考链接)。

  1. iOS 检查是否有 auth_token。如果否,请继续执行第 2 步,否则请执行第 4 步。
  2. iOS 通过发送只有我的 iOS 应用和服务器知道如何生成的特殊签名来请求 auth_token。
  3. WEB 验证特殊签名并创建一个唯一的 auth_token 保存在数据库中并发送回 iOS 应用程序。
  4. iOS 通过发送 auth_token 和生成的签名(同样只有我的 iOS 和服务器知道如何生成的签名)来请求数据。
  5. WEB 验证数据库中是否存在 auth_token。然后它会生成一个 auth_signature 并验证请求是否来自我的 iOS 应用。
  6. WEB 响应数据和新生成的 auth_token。
  7. WEB 会从 DB 中删除之前的 auth_token。
  8. iOS 在本地保存新的 auth_token 并使用数据。
  9. 重复步骤 4-8;如果响应是未经授权的 401,请从第 1 步重新开始。

参考资料:

@keighl 的这个 GitHub Gist 是我的起点,迄今为止我发现的最好的例子: https://gist.github.com/4336694

Railscast:保护 API: http://railscasts.com/episodes/352-securing-an-api

【讨论】:

  • 如果您为每个请求生成一个新的 auth_token,那么在我看来,您可以用简单的质询-响应替换所有这些步骤:1)iOS 使用 api 请求发送生成的 sig,2)服务器验证 sig 并发送 api 响应或拒绝访问。少了很多乱七八糟的。按照您概述流程的方式,如果第 6 步出现网络错误,您的客户端和服务器现在有冲突的身份验证令牌。
  • 可以在客户端生成的特殊签名是不安全的。它可以被逆向工程。这种方法总比没有好,但仍然不会阻止其他应用程序使用您的 API。查看类似问题security.stackexchange.com/questions/141104/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-10
  • 2015-09-23
  • 2015-06-13
  • 2015-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多