Access control allow origin error on tornado

624 views
Skip to first unread message

yldaed...@gmail.com

unread,
Oct 13, 2018, 2:26:23 PM10/13/18
to Tornado Web Server
I am  struggling with a tornado redirect issue, I am using python 3.6.3, tornado 5.1.1. Boiling down the code to the minimum to show the problem. Here is my html file. When it loads it makes a get on the /login end point. In the /login 
end point I am doing a self.redirect() to example.com. See Python code below the html. 

<!DOCTYPE html>
<html>

<script src="https://d3js.org/d3.v3.js"></script>
<script>


    function login(){
      var params = window.location.search;
      d3.xhr("http://localhost:8000/login")
        .get(function(err, data){
            console.log(data);
        });
    }

</script>
<body onload="login()">
<p id="params"></p>
</body>
</html>

The python code is below. When I run it with python3 server.py, the html loads and does GET on the /login and then the browser gives an error:
Failed to load http://example.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
What am I doing wrong?

import tornado.ioloop
import tornado.web
import json
import os

R_URL='http://example.com'
class MainHandler(tornado.web.RequestHandler):
def set_default_headers(self):
print("setting headers!!!")
self.set_header("access-control-allow-origin", "*")
self.set_header('Access-Control-Allow-Methods', 'GET, PUT, DELETE, OPTIONS')
self.set_header("Access-Control-Allow-Credentials", "true")
self.set_header("Access-Control-Allow-Headers",
"Authorization, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, X-Requested-By, If-Modified-Since, X-File-Name, Cache-Control")

def get(self):
print("GET: MainHandler::localhost")
self.redirect(R_URL)
#self.get(R_URL)

def post(self):
print("Received POST")
self.redirect(R_URL)


def make_app():
root = os.path.dirname(__file__)
print("root", root)
application = tornado.web.Application([
(r"/login", MainHandler),
(r"/(.*)", tornado.web.StaticFileHandler, {"path": root, "default_filename": "index.html"}),
])
return application


if __name__ == "__main__":
app = make_app()
app.listen(8000)
print("Listening on port 8000")
tornado.ioloop.IOLoop.current().start()

Ben Darnell

unread,
Oct 14, 2018, 10:56:55 AM10/14/18
to Tornado Mailing List
Everything is fine on your `/login` endpoint. The error is coming from example.com. That site needs to serve the access-control-allow-origin headers too for the XMLHttpRequest to be able to see it. Since you've used example.com here I can't tell what you're really trying to do. If you're redirecting to a site you control, and setting access-control-allow-origin on it is appropriate from a security perspective, you can do so. If it's a site you can't control, you'll have to find some other way to do this because you won't be able to do a cross-site XMLHttpRequest to it.

-Ben

--
You received this message because you are subscribed to the Google Groups "Tornado Web Server" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-tornad...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

yldaed...@gmail.com

unread,
Oct 14, 2018, 3:04:57 PM10/14/18
to Tornado Web Server
I don't think what you are saying is correct.. example.com should not care if somebody is getting redirected to it. But assuming you are correct, do you have an example of a website that would work in the snippet of code I have? 
The other reason why I think this does not depend on example.com is that if I directly hit the /login endpoint  (http://localhost:8000/login) from the browser the redirect works fine. For some reason the browser throws an error when I do a get on /login from the javascript code.

Ben Darnell

unread,
Oct 14, 2018, 3:16:07 PM10/14/18
to Tornado Mailing List
On Sun, Oct 14, 2018 at 3:05 PM <yldaed...@gmail.com> wrote:
I don't think what you are saying is correct.. example.com should not care if somebody is getting redirected to it. But assuming you are correct, do you have an example of a website that would work in the snippet of code I have? 

Example.com doesn't care if a browser view is being redirected to it, but XMLHttpRequest does care. You can't use XHR to read from a site that doesn't specifically allow this. The redirect would be fine if it were a regular redirect (is that what you want? that after the login, the browser does a regular redirect to example.com? In that case you need to return a regular response from `/login` and then have the javascript that receives this response perform the regular redirect).

I can't point you to a site that would work for this kind of redirect because most sites won't and shouldn't allow it. The restrictions on XHR and access-control-allow-origin are part of the complex and subtle web security model. You only want to enable `access-control-allow-origin: *` on URLs that have been designed with this usage in mind. 
 
The other reason why I think this does not depend on example.com is that if I directly hit the /login endpoint  (http://localhost:8000/login) from the browser the redirect works fine. For some reason the browser throws an error when I do a get on /login from the javascript code.

Yes, XHR behaves very differently from regular browser views. You'll generally need to have one set of server-side endpoints for regular browsers and a separate set for javascript. I wish I could point you to a good document or book explaining this stuff, but I barely understand the browser side of things myself. 

-Ben

Yldaed Suriv

unread,
Oct 14, 2018, 3:32:32 PM10/14/18
to python-...@googlegroups.com
Ok I guess what you said makes it somewhat more clear than before.. taking a step back it appears to me that any Javascript code (that might not be written by me) that is making a GET on my backend server would not like to get redirected to some other website without its agreement. Is that what you mean?
 in that case can you tell me how to do a regular redirect? In my /login end point I have to return a response? This is where it is not clear to me. I am also new to Tornado in general. 

Ben Darnell

unread,
Oct 14, 2018, 4:03:16 PM10/14/18
to Tornado Mailing List
On Sun, Oct 14, 2018 at 3:32 PM Yldaed Suriv <yldaed...@gmail.com> wrote:
Ok I guess what you said makes it somewhat more clear than before.. taking a step back it appears to me that any Javascript code (that might not be written by me) that is making a GET on my backend server would not like to get redirected to some other website without its agreement. Is that what you mean?

It's not about the redirect, it's about what javascript on one site is allowed to *see* from another. When you make an XHR, and the target of that XHR does a redirect, the redirect is happening inside the XHR and not in the user's browser window, and the results go back to the javascript code. To navigate the browser window to a url, you have to take action outside the XHR. 
 
 in that case can you tell me how to do a regular redirect? In my /login end point I have to return a response? This is where it is not clear to me. I am also new to Tornado in general. 

You're doing a regular redirect correctly for a plain non-javascript form-based login. To do login with javascript instead of plain forms is an entirely different thing that I don't know much about. Your questions have more to do with javascript than tornado, so I suggest asking them in javascript-focused forums.

-Ben

gzg

unread,
Feb 17, 2019, 7:53:10 AM2/17/19
to Tornado Web Server
that's just a knowledge point about js/XHR, nothing to do with Tornado...



在 2018年10月15日星期一 UTC+8上午3:32:32,Yldaed Suriv写道:
Reply all
Reply to author
Forward
0 new messages