issues with Access-Control-Allow-Origin

802 views
Skip to first unread message

elishowk

unread,
Jun 30, 2011, 1:52:13 PM6/30/11
to ucen...@googlegroups.com
Hi,

I'm using the develop branch behind a reverse proxy, and coding a website served outside of yaws, directly from a nginx server. I pointed uce.createClient to my ucengine backend, and since I have a security error at the beginning of index loading :

XMLHttpRequest cannot load http://myucengineserver/api/0.5/presence/. Origin http://localhost is not allowed by Access-Control-Allow-Origin.

Here I serve my website from localhost and have the backend on a distant machine. But it's the same when the website is served on the same machine but on different port.
Then I tested some curl requests that shows the response headers of unsuccessfull requests does not include the desired header. For example :


curl -v "http:/myucengineserver/api/0.5/presence/"
* About to connect() to myucengineserver port 80 (#0)
* Trying xx.XX.xx.XX... connected
* Connected to myucengineserver (xx.XX.xx.XX) port 80 (#0)
> GET /api/0.5/presence/ HTTP/1.1
> User-Agent: curl/7.21.3 (x86_64-pc-linux-gnu) libcurl/7.21.3 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.18
> Host: myucengineserver:80
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.0.4
< Date: Thu, 30 Jun 2011 17:39:28 GMT
< Content-Type: application/json
< Connection: keep-alive
< Content-Length: 21
<
* Connection #0 to host myucengineserver left intact
* Closing connection #0
{"error":"not_found"}

I took a look at the erlang sources, but as I'm not an erlang dev yet, I could only make suppositions... I found in  src/helpers/json_helpers.erl that some response are allowed to go without the add_cors_headers call. And especially that error handler like unexpected_error() does not either. Is it a normal behaviour ? Isn't it possible to always have this "Access-Control-Allow-Origin: *" headers ?
On the other hand, when request are PUT or DELETE, is the "preflighted request" mechanism is implemented ? (see http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/ and https://developer.mozilla.org/En/Server-Side_Access_Control)

Hoping I've been clear engouh, I'm looking forward for your answer, and for the moment continue to serve everything from the same yaws server.
Cheers

François de Metz

unread,
Jun 30, 2011, 2:08:25 PM6/30/11
to ucen...@googlegroups.com

We have a case when Access-Control-Allow-Origin header is not set, this
only when the Host header is not recognized. We have some plan to allow
specific authorization header per host.

For you issue, you have to check the Host header and if this host is
registered in ucengine config file. On the latest develop branch, I see
the Access-Control-Allow-Origin header.
I will remove the host header check in U.C.Engine code, this is very
confusing.

> On the other hand, when request are PUT or DELETE, is the "preflighted
> request" mechanism is implemented ?
> (see http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/ and https://developer.mozilla.org/En/Server-Side_Access_Control)

We don't support OPTIONS method. This is required only for firefox < 4.
Do you have an issue with newest browsers ?

> Hoping I've been clear engouh, I'm looking forward for your answer, and
> for the moment continue to serve everything from the same yaws server.
> Cheers

François


signature.asc

elishowk

unread,
Jul 1, 2011, 5:03:58 AM7/1/11
to ucen...@googlegroups.com
Thanks for your rapid feedback.
This Host header check is quite confusing indeed, but may be a good documentation page about that could resolve that ?
I'll check the Host value I send when deploying my UCE-based website on another domain, and give you an update.

About the cross-origin sharing policy, I asked this question, but I still have to check when I'll resolve the previous issue.

Anyway, are you sure about the fact that it's only valid for firefox < 4 ? I recently had to implement server-side this OPTIONS request handler to allow cross-origin PUT and DELETE requests (with Access-Control-Allow-Methods) but also GET and POST with application/json content-type bodies (with Access-Control-Allow-Headers). This seems to be a requirement aside of the Access-Control-Allow-Origin header for any cross-site requests. I'll give you a feedback as soon as possible.

Elias.

elishowk

unread,
Jul 1, 2011, 8:24:25 AM7/1/11
to ucen...@googlegroups.com
Salut,

I have updates about my usage of the javascriot client lib outside of the API server. I sat up my uce.cfg with my external host, but nothing changed.
I have confirmation that with Firefox 4 or 5, and Chrome, the first POST ajax request pre-sends an OPTIONS requests automatically, asking the server to verify its cross-site request.
This behaviour is described here and is standard http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/
But the problem here, is that OPTIONS on the UCEngine responds 404, without any cross-site specific headers.

Here is the firebug information of the failing request.

OPTIONS presence
404 Not Found

En-têtes
Réponse


HTTP/1.1 404 Not Found
Server: nginx/1.0.4
Date: Fri, 01 Jul 2011 11:52:28 GMT
Content-Type: application/json
Connection: keep-alive
Content-Length: 21


Requête
OPTIONS /api/0.5/presence/ HTTP/1.1
Host: myucewebsite
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:5.0) Gecko/20100101 Firefox/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://myucewebsite
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-requested-with
Pragma: no-cache
Cache-Control: no-cache

Here is an example of what worked for me in a python/flask rest server (also using json bodies) experiment I coded lately ( https://github.com/elishowk/flaskexperiment/blob/master/commonecouteserver/__init__.py )

As you can see in the after_request() trigger function (line 64)
 :
  1.  always add to the response : 'Access-Control-Allow-Origin: *'
  2. if it's an OPTIONS request :
    1. allow all methods by adding to the response :
      Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
    2. copy the special allow header in the response (created automatically by the XMLHttpRequest object) :
      response.headers['Access-Control-Allow-Headers'] = request.headers['Access-Control-Request-Headers']
I hope this will help to fix this issue.
Cheers.

François de Metz

unread,
Jul 4, 2011, 10:03:48 AM7/4/11
to ucen...@googlegroups.com
Hi,

On 07/01/2011 02:24 PM, elishowk wrote:
> Salut,
>
> I have updates about my usage of the javascriot client lib outside of
> the API server. I sat up my uce.cfg with my external host, but nothing
> changed.
> I have confirmation that with Firefox 4 or 5, and Chrome, the first POST
> ajax request pre-sends an OPTIONS requests automatically, asking the
> server to verify its cross-site request.

This not really true with firefox >= 4. If you don't set an custom
header, the browser will make the request. The OPTIONS request will only
occurs with PUT and DELETE requests.
We have a workaround in uce.js with a special parameter *_method*. You
can override the current verb in case of POST request.
If you want to support firefox < 4, I can merge your pull request.

François

signature.asc
Reply all
Reply to author
Forward
0 new messages