如何保护我在应用内发起的REST调用?

11 投票
3 回答
4203 浏览
提问于 2025-04-16 18:09

我有一个应用程序,它有一个“私有”的REST API;我在自己的网站上使用RESTful的URL进行Ajax调用。不过,这样不安全,任何人只要知道这些URL的格式,就可以进行相同的调用。

有什么好的(或者说是标准的)方法来保护这些调用吗? 如果我打算将来发布一个API,现在考虑使用像OAuth这样的东西是否值得,还是说我把两种不同的策略搞混了?

我正在使用Google App Engine和Python,以及Tipfy。

3 个回答

1

在你现在的情况中,使用OAuth可能有点过于复杂了(可能不安全),因为OAuth的设计目的是为了让第三方服务能够代表用户访问资源。

通过授权用户保护AJAX请求

根据我所了解,你可以控制客户端、资源和身份验证;所以你只需要确保URL的访问安全,可能还需要通过SSL来保护客户端和服务器之间的通信[2]。

因此,可以使用Tipfy的身份验证扩展来保护你的URL:

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扩展中内置了这个功能,但它不是AJAX的。相反,可以使用会话扩展为所有请求添加一个“authenticity_token”,这个token需要在服务器上进行验证。

4

保护一个JavaScript客户端几乎是不可能的。在服务器端,你没有办法百分之百区分是人类在用浏览器,还是一个精心制作的脚本在操作。

SSL可以加密数据在传输过程中,但在到达目的地时会解密,所以这并不能解决问题。它可以防止中间人攻击,但对验证原始客户端的合法性没有帮助。

OAuth在两个服务器之间的请求安全性上表现不错,但对于JavaScript客户端来说,帮助不大:任何人只要查看你的JavaScript代码,就能找到你的消费者密钥和秘密,然后他们就可以伪造签名请求。

不过,有一些方法可以减轻API被抓取的风险:

  • 当有人访问你的网站时,生成短期有效的会话cookie。调用REST API时需要有效的会话cookie。
  • 生成短期有效的请求令牌,并将其包含在你网站的HTML中;每个API请求都需要有效的请求令牌。
  • 要求你网站的用户登录(比如使用Google账户或OpenID);在处理API请求之前检查认证cookie。
  • 限制API请求的频率。如果在短时间内从同一个客户端收到过多请求,就阻止他们。
6

一定要看看 OAuth

它正在迅速成为保护REST API的“事实标准”,很多大公司都在使用它,比如 谷歌推特脸书,这些只是其中的一些例子。

在GAE上使用Python,你有两个选择:

我认为最简单的方法是使用David Larlet为 Django提供的OAuth支持库,这个库可以在BitBucket上找到。

不过,因为你不使用Django,或许你想看看在GitHub上可以找到的 python-oauth2库,这个库被认为是Python 2.4+中最新和经过单元测试的OAuth实现。

无论如何,我觉得使用OAuth会比自己开发一个服务安全解决方案要好得多。

撰写回答