简体   繁体   English

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

[英]How to prevent direct access to my JSON service?

I have a JSON web service to return home markers to be displayed on my Google Map. 我有一个JSON Web服务来返回要在我的Google地图上显示的家庭标记。

Essentially, http://example.com calls the web service to find out the location of all map markers to display like so: 基本上, http://example.com调用Web服务来查找所有地图标记的位置,如下所示:

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

And it returns a JSON string such as: 它返回一个JSON字符串,例如:

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

So on my index.html page, I take that JSON string and place the map markers. 所以在我的index.html页面上,我获取该JSON字符串并放置地图标记。

However, what I don't want to have happen is people calling out to my JSON web service directly . 但是,我不希望发生的是人们直接呼叫我的JSON Web服务。

I only want http://example.com/index.html to be able to call my http://example.com/json/ web service ... and not some random dude calling the /json/ directly. 我只希望http://example.com/index.html能够调用我的http://example.com/json/网络服务...而不是一些随机的家伙直接调用/json/

Quesiton : how do I prevent direct calling/access to my http://example.com/json/ web service? Quesiton :如何阻止直接呼叫/访问我的http://example.com/json/网络服务?


UPDATE: 更新:

To give more clarity, http://example.com/index.html call http://example.com/json/?zipcode=12345 ... and the JSON service 为了更加清晰,请http://example.com/index.html调用http://example.com/json/?zipcode=12345 ...和JSON服务
- returns semi-sensitive data, - 返回半敏感数据,
- returns a JSON array, - 返回一个JSON数组,
- responds to GET requests, - 响应GET请求,
- the browser making the request has JavaScript enabled - 发出请求的浏览器启用了JavaScript

Again, what I don't want to have happen is people simply look at my index.html source code and then call the JSON service directly. 同样,我不希望发生的是人们只需查看我的index.html源代码然后直接调用JSON服务。

There are a few good ways to authenticate clients. 有一些很好的方法来验证客户端。

  • By IP address. 按IP地址。 In Apache, use the Allow / Deny directives. 在Apache中,使用Allow / Deny指令。
  • By HTTP auth: basic or digest. 通过HTTP身份验证:基本或摘要。 This is nice and standardized, and uses usernames/passwords to authenticate. 这很好并且标准化,并使用用户名/密码进行身份验证。
  • By cookie. 通过cookie。 You'll have to come up with the cookie. 你必须拿出cookie。
  • By a custom HTTP header that you invent. 通过您发明的自定义HTTP标头。

Edit: 编辑:

I didn't catch at first that your web service is being called by client-side code. 我一开始并没有意识到客户端代码正在调用您的Web服务。 It is literally NOT POSSIBLE to prevent people from calling your web service directly, if you let client-side Javascript do it. 如果您让客户端Javascript这样做,那么阻止人们直接调用您的Web服务实际上是不可能的。 Someone could just read the source code. 有人可以阅读源代码。

Some more specific answers here, but I'd like to make the following general point: 这里有一些更具体的答案,但我想提出以下一般观点:

Anything done over AJAX is being loaded by the user's browser. 通过AJAX完成的任何操作都由用户的浏览器加载。 You could make a hacker's life hard if you wanted to, but, ultimately, there is no way of stopping me from getting data that you already freely make available to me . 如果你愿意的话,你可以让黑客的生活变得艰难,但是,最终, 没有办法阻止我获取你已经免费提供给我的数据 Any service that is publicly available is publicly available, plain and simple. 任何公开可用的服务都是公开的,简单明了。

Accept only POST requests to the JSON-yielding URL. 仅接受对JSON产生的URL的POST请求。 That won't prevent determined people from getting to it, but it will prevent casual browsing. 这不会阻止坚定的人进入它,但它会阻止随意浏览。

If you are using Apache you can set allow/deny on locations. 如果您使用的是Apache,则可以在位置上设置允许/拒绝。

http://www.apachesecurity.net/ http://www.apachesecurity.net/

or here is a link to the apache docs on the Deny directive 或者这里是Deny指令上apache文档的链接

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

EDITS (responding to the new info). 编辑(回复新信息)。

The Deny directive also works with environment variables. Deny指令也适用于环境变量。 You can restrict access based on browser string (not really secure, but discourages casual browsing) which would still allow XHR calls. 您可以根据浏览器字符串限制访问(不是非常安全,但不鼓励随意浏览),这仍然允许XHR调用。

I would suggest the best way to accomplish this is to have a token of some kind that validates the request is a 'good' request. 我建议最好的方法是获得某种类型的令牌,验证请求是一个“好”的请求。 You can do that with a cookie, a session store of some kind, or a parameter (or some combination). 您可以使用cookie,某种会话存储或参数(或某种组合)来实现。

What I would suggest for something like this is to generate a unique url for the service that expires after a short period of time. 我建议这样的事情是为服务生成一个独特的URL,在短时间后过期。 You could do something like this pretty easily with Memcache. 你可以用Memcache很容易地做这样的事情。 This strategy could also be used to obfuscate the service url (which would not provide any actual security, but would raise the bar for someone wanting to make direct calls). 此策略也可用于混淆服务URL(这不会提供任何实际的安全性,但会为想要直接呼叫的人提高标准)。

Lastly, you could also use public key crypto to do this, but that would be very heavy. 最后,您还可以使用公钥加密来执行此操作,但这将非常繁重。 You would need to generate a new pub/priv key pair for each request and return the pubkey to the js client (here is a link to an implementation in javascript) http://www.cs.pitt.edu/~kirk/cs1501/notes/rsademo/ 您需要为每个请求生成一个新的pub / priv密钥对,并将pubkey返回给js客户端(这里是一个javascript实现的链接) http://www.cs.pitt.edu/~kirk/cs1501 /笔记/ rsademo /

You can add a random number as a flag to determine whether the request are coming from the page just sent: 您可以添加随机数作为标志,以确定请求是否来自刚刚发送的页面:

1) When generates index.html , add a random number to the JSON request URL: 1)生成index.html ,将随机数添加到JSON请求URL:

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

New: http://example.com/json/?zipcode=12345&f=234234234234234234 新增内容: http://example.com/json/?zipcode=12345&f=234234234234234234http://example.com/json/?zipcode=12345&f=234234234234234234

Add this number to the Session Context as well. 将此数字添加到会话上下文中。

2) The client browser renders the index.html and request JSON data by the new URL. 2)客户端浏览器呈现index.html并通过新URL请求JSON数据。

3) Your server gets the json request and checks the flag number with Session Context . 3)您的服务器获取json请求并使用会话上下文检查标志号。 If matched, response data. 如果匹配,则响应数据。 Otherwise, return an error message. 否则,返回错误消息。

4) Clear Session Context by the end of response, or timeout triggered. 4)在响应结束或超时触发时清除会话上下文

You'll probably have to have some kind of cookie-based authentication. 您可能必须进行某种基于cookie的身份验证。 In addition, Ignacio has a good point about using POST. 此外,Ignacio对使用POST有一个很好的观点。 This can help prevent JSON hijacking if you have untrusted scripts running on your domain. 如果您的域上运行了不受信任的脚本,这可以帮助防止JSON劫持 However, I don't think using POST is strictly necessary unless the outermost JSON type is an array. 但是,除非最外面的JSON类型是数组,否则我认为不必使用POST。 In your example it is an object. 在您的示例中,它是一个对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM