如何保护我在应用内进行的 REST 调用?

Posted

技术标签:

【中文标题】如何保护我在应用内进行的 REST 调用?【英文标题】:How do I secure REST calls I am making in-app? 【发布时间】:2011-08-30 19:28:26 【问题描述】:

我有一个具有“私有”REST API 的应用程序;从我自己的网页进行 Ajax 调用时,我使用 RESTful URL。但是,这是不安全的,任何人只要知道 URL 模式就可以进行同样的调用。

保护这些调用的最佳(或标准)方法是什么? 如果我打算在未来发布 API,是否值得现在研究 OAuth 之类的东西,或者我是否混合了两种不同的策略一起?

我正在使用 Google App Engine for Python 和 Tipfy。

【问题讨论】:

谢谢大家的意见。我选择 OAuth 是因为它是标准的,现在和将来都会为我服务。 【参考方案1】:

一定要看看OAuth

它正在迅速成为保护 REST API 的“事实上的”标准,许多大公司都在使用它,包括 Google、Twitter 和 Facebook 等等。

对于 GAE 上的 Python,您有两种选择:

最直接的方法 (恕我直言) 是使用 David Larlet 的 OAuth Support in Django 库,可在 BitBucket 上找到。

但是由于您没有使用 Django,也许您想看看 GitHub 上提供的 python-oauth2 库,它被认为是 Python 2.4 的 OAuth 的最新且经过单元测试的实现+。

无论哪种方式,我认为使用 OAuth 比推出自己的服务安全解决方案要好得多。

【讨论】:

如果你打算使用 OAuth,你应该使用 OAuth 2.0 wiki.oauth.net/w/page/25236487/OAuth-2 -- github.com/progrium/oauth2-appengine 为什么要使用 OAuth 从您自己的网页到您自己的“私有”REST API? @Erick 网页是客户端,服务器是资源提供者。【参考方案2】:

保护 javascript 客户端几乎是不可能的;在服务器上,您没有万无一失的方法来区分使用 Web 浏览器的人和精心设计的脚本。

SSL 通过网络对数据进行加密,但在边缘进行解密,所以这无济于事。它可以防止中间人攻击,但不会验证原始客户端的合法性。

OAuth 可以很好地保护两台服务器之间的请求,但对于 Javascript 客户端来说,它并没有真正的帮助:任何阅读您的 javascript 代码的人都可以找到您的使用者密钥/秘密,然后他们可以伪造签名的请求。

您可以采取一些措施来减轻 API 抓取:

当有人访问您的网站时生成短期会话 cookie。需要有效的会话 cookie 才能调用 REST API。 生成短期请求令牌并将其包含在您的网站 html 中;在每个 API 请求中都需要一个有效的请求令牌。 要求您网站的用户登录(Google 帐户/OpenID);在处理 API 请求之前检查 auth cookie。 速率限制 API 请求。如果您在短时间内看到来自某个客户的请求过多,请阻止它们。

【讨论】:

【参考方案3】:

在您当前的场景 (potentially insecure) 中,OAuth 将是多余的,因为它旨在授权第三方服务访问有关用户行为的资源。

通过授权用户保护 AJAX 请求

AFAICT,您可以控制客户端、资源和身份验证;因此,您只需要保护对 URL 的访问以及可能通过 SSL [2] 进行客户端和服务器之间的通信。

所以,请使用 Tipfy 的 auth extension 来保护您的网址:

from tipfy import RequestHandler, Response
from tipfy.ext.auth import AppEngineAuthMixin, user_required

class MyHandler(RequestHandler, AppEngineAuthMixin):
    @user_required
    def get(self, **kwargs):
        return Response('Only logged in users can see this page.')

在没有授权用户的情况下保护 AJAX 请求

如果用户未知,则可以应用 CSRF 预防措施来帮助保护 REST 服务不被“未经授权”的客户端调用。 Tipfy 内置了 WTForms extension,但它不是 AJAX。相反,session extension 可用于将“authenticity_token”应用于所有需要在服务器上验证的调用。

【讨论】:

谢谢,埃里克。唯一的问题是即使有人没有登录,我也需要使用 Ajax。是否有来自 Tipfy 的另一个装饰器可以实现这个目的? @Wraith,如何从无效用户中识别有效用户? 任何人都可以使用网站的基本功能,但有些功能受到限制。当需要有效的登录用户时,使用装饰器是明确的,但我仍然对匿名用户使用 Ajax。 我唯一能想到的就是使用tipfy会话扩展中的“secret_key”功能来创建某种哈希验证,以确保调用来自您的AJAX应用程序。

以上是关于如何保护我在应用内进行的 REST 调用?的主要内容,如果未能解决你的问题,请参考以下文章

在烧瓶中保护 REST api

什么是 OAuth,它如何保护 REST API 调用? [关闭]

如何在 Android 中保护调用 web 服务

使用客户端令牌保护 REST API 调用

如何列出对服务器进行的 REST API 调用 [重复]

如何使用 Flask-USER 管理保护 Flask-RESTful?