龙卷风 get_secure_cookie() 间歇性地返回值

Tornado get_secure_cookie() returning value intermittently

在龙卷风中使用 get_secure_cookie() 进行重定向时遇到问题。

get_current_user() 方法似乎被多次调用,并间歇性地通过 self.get_secure_cookie("userid").

找到可用的数据

以下代码让我在登录后访问受保护的页面,但不会正确重定向:

class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        username, self._user_perms = database.get_user_info(int(self.get_secure_cookie("userid") or 0))
        log.warning("WE HAVE A USERID %r and username: %r", self.get_secure_cookie("userid"), username)
        if self._user_perms: return username # If perms==0, the user has been banned, and should be treated as not-logged-in.

并且在输出日志中:

2015-02-24 14:37:36,399:WARNING:__main__:WE HAVE A USERID None and username: None
2015-02-24 14:37:36,412:WARNING:__main__:WE HAVE A USERID None and username: None
2015-02-24 14:37:36,412:WARNING:__main__:WE GO:  u'/submit' AS None
2015-02-24 14:37:36,413:WARNING:__main__:WE HAVE A USERID None and username: None
2015-02-24 14:37:36,425:WARNING:__main__:WE HAVE A USERID None and username: None
2015-02-24 14:37:38,723:WARNING:__main__:WE HAVE A USERID '2' and username: u'My Name'

登录class如下:

class Login(BaseHandler):
    def get(self):
        form = UserForm()
        username = self.get_current_user()
        if self.get_current_user():
            self.redirect(self.get_argument('next', '/')) # Change this line
            return
        else:
            self.write(templates.load("login.html").generate(compiled=compiled, form=form, \
                                errormessage=errormessage, user_name=self.current_user))

    def post(self):
        form = UserForm(self.request.arguments)
        if form.validate():
            user_id = database.verify_user(self.get_argument('email'),\
                                self.get_argument('password'))
            if user_id:
                user_name, perms = database.get_user_info(user_id)
                if perms: self.set_secure_cookie("userid", str(user_id)) 
                self.redirect(self.get_argument("next", "/"))
            else:
                notice = "LOGIN FAILED. PLEASE TRY AGAIN."
                self.write(templates.load("login.html").generate(compiled=compiled, form=form, \
                                        notice=notice, user_name=self.current_user ))
        else:
            self.set_status(400)
            self.write(form.errors)

我认为 secure_cookie 可能需要一些时间才能访问并尝试将 time.sleep(2) 放入其中并获得相同(慢得多)的结果。

我还没有看到什么?

更新:

如下所述,最终成功的原因是:

templates/login.html中:

<input type="hidden" name="next" value="{{ next }}" />

tornado app中:

#within the Login(BaseHandler) class
self.write(templates.load("login.html").generate(compiled=compiled, form=form, next=self.get_argument('next', "/"),
                        errormessage=errormessage, user_name=self.current_user, notice=notice ))

'next' 参数似乎没有通过表单传递。您需要将其传递给 login.html 表单,然后将其传回,例如使用隐藏的输入元素。然后它将在 POST 端点可用。