如何防止直接访问我的JSON服务?

时间:2010-04-05 03:04:31

标签: javascript web-services security json

我有一个JSON网络服务来返回我的Google地图上显示的家庭标记。

基本上,http://example.com调用Web服务来查找要显示的所有地图标记的位置,如下所示:

http://example.com/json/?zipcode=12345

它返回一个JSON字符串,例如:

{"address": "321 Main St, Mountain View, CA, USA", ...}

因此,在我的index.html页面上,我会使用该JSON字符串并放置地图标记。

但是,我不希望发生的是人们直接呼叫我的JSON网络服务

我只希望http://example.com/index.html能够拨打我的http://example.com/json/网络服务...而不是一些随机的家伙直接拨打/json/

问题:如何阻止直接呼叫/访问我的http://example.com/json/网络服务?


更新

为了更清晰,http://example.com/index.html调用http://example.com/json/?zipcode=12345 ...和JSON服务
- 返回半敏感数据,
- 返回一个JSON数组,
- 响应GET请求,
- 发出请求的浏览器启用了JavaScript

同样,我不希望发生的是人们只是查看我的index.html源代码,然后直接调用JSON服务。

6 个答案:

答案 0 :(得分:9)

有一些很好的方法来验证客户端。

  • 按IP地址。在Apache中,使用Allow / Deny指令。
  • 通过HTTP身份验证:基本或摘要。这很好并且标准化,并使用用户名/密码进行身份验证。
  • 通过cookie。你必须拿出cookie。
  • 通过您发明的自定义HTTP标头。

编辑:

我一开始并没有意识到客户端代码正在调用您的Web服务。如果您让客户端Javascript这样做,那么阻止人们直接调用您的Web服务实际上是不可能的。有人可以阅读源代码。

答案 1 :(得分:5)

这里有一些更具体的答案,但我想提出以下一般观点:

通过AJAX完成的任何操作都由用户的浏览器加载。如果你愿意,你可以让黑客的生活变得艰难,但是,最终,没有办法阻止我获取你已经免费提供给我的数据。任何公开的服务都是公开的,简单明了。

答案 2 :(得分:2)

仅接受对JSON产生URL的POST请求。这不会阻止坚定的人进入它,但它会阻止随意浏览。

答案 3 :(得分:1)

如果您使用的是Apache,则可以在位置设置允许/拒绝。

http://www.apachesecurity.net/

或者这里是拒绝指令

上的apache文档的链接

http://httpd.apache.org/docs/2.0/mod/mod_access.html#deny

编辑(回复新信息)。

Deny指令也适用于环境变量。您可以根据浏览器字符串限制访问(不是非常安全,但不鼓励随意浏览),这仍然允许XHR调用。

我建议最好的方法是使用某种类型的令牌来验证请求是一个“好”的请求。您可以使用cookie,某种会话存储或参数(或某种组合)来实现。

我建议这样的事情是为服务生成一个独特的URL,在短时间后过期。你可以用Memcache很容易地做这样的事情。此策略也可用于混淆服务URL(这不会提供任何实际的安全性,但会为想要直接呼叫的人提高标准)。

最后,您还可以使用公钥加密来执行此操作,但这将非常重。您需要为每个请求生成一个新的pub / priv密钥对,并将pubkey返回给js客户端(这里是javascript中实现的链接)http://www.cs.pitt.edu/~kirk/cs1501/notes/rsademo/

答案 4 :(得分:1)

您可以添加一个随机数作为标志,以确定该请求是否来自刚刚发送的页面:

1)生成index.html时,将随机数添加到JSON请求URL:

旧:http://example.com/json/?zipcode=12345

新:http://example.com/json/?zipcode=12345&f=234234234234234234

将此号码添加到会话上下文

2)客户端浏览器呈现index.html并通过新URL请求JSON数据。

3)您的服务器获取json请求并使用会话上下文检查标志号。如果匹配,则响应数据。否则,返回错误消息。

4)在响应结束或超时触发时清除会话上下文

答案 5 :(得分:0)

您可能需要进行某种基于cookie的身份验证。此外,Ignacio对使用POST有一个很好的观点。如果您的域上运行了不受信任的脚本,这有助于防止JSON hijacking。但是,除非最外面的JSON类型是数组,否则我认为不必使用POST。在您的示例中,它是一个对象。