Question

Question

Since Tornado append a next query string parameter, which contain the URL of the resource building the redirect URL, sometimes we can redirect the user back to the referring page after login or logout applying line self.redirect(self.get_argument("next", "/"))

But when I use this in the following code, It didn't work. Without login, when visiting Page /test, it will redirect to /login?next=%2Ftest, but the parameter next is always null and it will be redirect to root page instead of /test.

How can I fix this problem?

code

import os
import tornado.wsgi
import tornado.web
import tornado.options
import tornado.ioloop

class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        return self.get_secure_cookie("user")

class MainHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self):
        self.render('index.html', user = self.current_user)

class LoginHandler(BaseHandler):
    def get(self):
        if self.get_current_user():
            self.redirect('/')
            return
        self.render('login.html')

    def post(self):
        self.set_secure_cookie("user", self.get_argument("username"))
        self.redirect(self.get_argument('next', '/'))

class LogoutHandler(BaseHandler):
    def get(self):
        if not self.get_current_user():
            self.redirect('/')
            return
        self.clear_cookie("user")
        self.redirect(self.get_argument("next", "/"))

class TestHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self):
        self.write("Testing!)

settings = { 
    "static_path" : os.path.join(os.path.dirname(__file__), "static"),
    "template_path" : os.path.join(os.path.dirname(__file__), "templates"),
    "login_url" : "/login",
    "cookie_secret" : "61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=",
    "gzip" : True,
    "debug" : True,
}

application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/login", LoginHandler),
    (r"/logout", LogoutHandler),
    (r"/test", TestHandler),
], **settings)

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
Was it helpful?

Solution

In the get method of LoginHandler, use the next argument for the redirect

...

class LoginHandler(BaseHandler):
    def get(self):
        if self.get_current_user():
            self.redirect(self.get_argument('next', '/')) # Change this line
            return
        self.render('login.html')

...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top