从iOS应用程序安全地访问数据库

23
我在比较MySQL和SQLite后选择了MySQL作为访问数据库的方式,因为我的iPhone应用程序需要从已经存在于MySQL中的在线数据库中拉取信息。
我认为传统的访问信息的方式是:在服务器上有一个php文件来进行访问。
iPhone应用程序将调用此php文件,并返回结果。
iOS应用程序将调用http://somewebsite.com/index.php?id=234,网站将打印出id = 234的用户名。

What happens in the background of an iPhone app

现在,这个过程有多安全?我会使用预编译语句和https。但是,如果有人找到了这个网站的URL呢?我如何保护自己免受滥用(某人可以生成所有用户的列表)?这是否是iPhone应用程序连接并从数据库获取信息的标准方式?

编辑:此外,假设我需要创建一个应用程序登录页面...我有一个MySQL数据库,其中包含用户名和密码(显然是哈希值)。使用$_GET变量来查看它们是否已经验证,是否安全。例如:https://somewebsite.com/checkauth.php?username=test&password=C3LyiJvTCQ14Q 并让php打印出是或否。下面是图片示例:

This is how the iPhone would authenticate a user This is how the iPhone would authenticate a user

我认为上述方法可能不安全,但我需要更多启示。
此外,我希望避免使用第三方API在应用程序中调用数据库,这不受苹果支持。

只是出于兴趣,您是否考虑过使用第三方OAuth供应商来进行身份验证?例如:https://dev59.com/imkv5IYBdhLWcg3w3Ug0 - Tom
为什么不使用众多优秀的Web应用程序框架中的一个呢?此外,几乎每个Web应用程序框架都有初学者级别的教程,其中当然也包括安全性和可能还有登录示例。 - CouchDeveloper
4个回答

23

最好的方法是设置一个API,与服务器上的数据库进行交互,您的iPhone应用程序只需查询API,并以机器可读格式返回数据,例如 JSON, 参见http://en.wikipedia.org/wiki/JSONhttp://json.org/。因此,对于用户登录,服务器可能会返回类似以下内容:

{
    "result": false,
    "error": "Invalid username or password"
}

以下代码是用PHP生成的:

echo json_encode(array(
    "result" => false, 
    "error" => "Invalid username or password"
));
另外请注意,你应该与之配合使用HTTP响应代码,例如401表示未经授权。
JSON可以在其格式中使用布尔和其他数据结构。几乎所有主要的编程语言都有对它的支持/库。
这样做的好处是允许您使用相同的API构建其他应用程序,例如Android版本或实际网站。
这个SO问题是移动应用程序安全的良好起点: Creating an API for mobile applications - Authentication and Authorization 主要要点是确保使用HTTPS。当发送用户凭据时,您可以返回一个可用于未来请求并存储在iPhone应用程序中以供未来访问的用户令牌(API密钥)。
例如:https://iphoneapp.com/notifications.json?key=98fy92473r92hAAIYEFG397qbqwiuUEAF 您的密钥应通过HTTP头或POST发送,以便不会记录在日志等中...
这种方法允许您删除/重新生成密钥,如果被破坏。您还可以在密钥和各种其他参数上设置速率限制。
另一个巨大的好处是通过构建自己的应用程序使用的API,意味着它将保持高标准,并且其他第三方公司也可以使用该API(如果您允许)。
编辑:此外,假设我需要创建一个应用程序登录页面...我有一个MySQL数据库,其中包含用户名和密码(已哈希)。使用$ _GET变量来查看它们是否经过身份验证是否安全。例如: https://somewebsite.com/checkauth.php?username=test&password=C3LyiJvTCQ14Q 您应该使用POST发送敏感数据,但任何服务都必须在某个时候登录。使用HTTPS应该是最有帮助的,因为它可防止窃听。在第一次身份验证之后,您可以返回令牌并获得上述好处。
至于用户登录,只要您的PHP符合良好的实践原则,就不应该有问题。如果您有疑问,请参见http://www.phptherightway.com/,它将有很大帮助。
如果可以/想要,请务必研究OAuth并加以利用。 这只是一个起点,不应逐字使用,需要进一步阅读和搜索。

"你应该使用POST方法发送敏感数据,但是任何服务在某个时候都需要登录。使用HTTPS应该是最有帮助的,因为它可以防止窃听。" 注意:这里仅第二句话才有意义。POST 方法并不比GET更安全。 - Wayne
@lwburk 我没有提到使用一个HTTP方法有任何好处。如果出现错误并显示URL怎么办?当不需要时,用户可以更容易地看到GET参数。不过我理解你的观点。 - SamV
使用 POST 来保证安全就像在明信片上写下秘密,然后争辩说如果卡片倒置并且秘密面朝下,那么秘密会更安全一样。但这毫无意义,任何人都可以翻过卡片。 - Wayne
@lwburk,我并不是在说这个,我是在谈论普通用户,而不是那些积极寻找这些信息的人。我绝对没有以任何方式暗示不同的HTTP方法会增加安全性。因为它们并不会。 - SamV

2
如果您正在寻找一种替代“从头开始构建API”的方法,我们使用了一个名为Kumulos的基于Web的服务,可在kumulos.com上获得快速简便的解决方案。
该服务允许开发人员连接到MySQL数据库,并通过网页构建数据模型和API,然后部署本地库到您的平台。我相信您还可以导入现有的数据模型。
一旦在网页上构建了数据模型,您就可以构建API并指定输入和输出参数。API是基于您执行的SQL操作类型建模的,例如SELECT、UPDATE、INSERT、DELETE。
在您的情况下,您需要建模一个接受用户名和(哈希)密码的登录/身份验证UI,对Users表中的数据进行验证,并返回身份验证结果。
一旦通过网页建模了API,您就可以“部署”您的配置并生成iOS、Android、PHP和其他本机库。
生成的Obj C库将被放置在您的项目中,您可以使用Objective C调用和委托来进行API的调用和响应。
Kumulos还包括一些其他功能,如数据导出、API调用计量以及他们称之为KScript。这实质上是在服务器上用JavaScript包装您的调用(也是通过网页配置),以极大地扩展您可以构建的API调用功能的灵活性和能力。
在过去几个月中,我们遇到了一些问题或支持问题,他们的支持非常出色。他们的后盾是在Rackspace上。我们目前有大约8到10个生产应用程序通过它们运行API,并且非常满意不必雇用API开发人员 :)

2
许多移动应用程序使用API从服务器获取和存储信息。找出其中一些端点并不复杂,但是返回敏感信息的未安全端点是一件危险的事情。
保护API的第一级别可以是创建一个“API密钥”来识别应用程序。该密钥被存储在服务器中,并在每个请求上进行检查。没有API密钥的请求应返回HTTP 401(未经授权)状态码。
API密钥还不足以满足所有需求,对于某些调用只能由特定用户执行的情况,需要传递身份验证信息以标识用户执行更新操作。
我不建议在每个请求上使用用户名/密码,而是让用户进行一次身份验证,然后让服务器发送回身份验证令牌,该应用程序可以用于执行将来的已认证调用。看看OAuth2作为潜在的授权框架。另请参阅OAuth 2.0-The Good, the Bad & the Ugly
我建议使用BShaffer PHP中的OAuth2服务器。另外,为了寻找替代方案,请参考保护REST API / Web服务的最佳实践

从你的问题看来,似乎有一个现有的子系统,我建议创建一个简单的接口,使子系统易于使用,并可在多个客户端上重复使用,而不是修改子系统以适应API。这通常称为门面设计模式

许多PHP框架都有包来实现自定义REST-like API。Symfony有FOSRestBundleFuelPHP具有开箱即用的REST控制器,而CodeIgniter具有REST服务器

总之:

  1. 创建一个简单的界面,从现有系统(REST API)中访问信息。
  2. 使用适当的身份验证机制(可能是OAuth2)保护您的私人信息。
  3. 使用现有的库和/或框架加速开发。
  4. 由此,您的代码将可重复使用于多个应用程序和平台!

-9
如果你想从IOS应用程序中访问数据库并将数据保存到数据库中,你必须使用中间件解决方案。

这个中间件解决方案就是WebService

在Microsoft ASP .Net中创建Web服务器,并在IOS应用程序中访问该WebService,这样就可以在两个不同的操作系统之间通信。

Webservice返回的是XML文档,可以使用xml解析器进一步解析。


我明白,但使用中间件解决方案有多安全...例如,我将使用PHP作为我的中间件。 - Arian Faurtosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接