1

即使我使用 Tornado 发送 401 状态代码,我也没有在 IE/Firefox 中看到密码提示:-

import tornado.ioloop
import tornado.web

class UserHandler(tornado.web.RequestHandler):
    def get(self, user_id):
        self.set_header('WWW-Authenticate', 'Basic realm="users"')
        self.send_error(status_code=401)

application = tornado.web.Application([
    (r"/users/(\w+)", UserHandler),
],debug=True)

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

此外,WWW-Authenticate 标头不会显示在响应标头中。当我不发送 401 状态时,它确实显示在标题中,但它仍然不显示密码提示。

4

2 回答 2

1

虽然我不知道为什么,但这很有效。

import tornado.ioloop
import tornado.web

class UserHandler(tornado.web.RequestHandler):
    def get(self, user_id):
        self.set_status(401)
        self.set_header('WWW-Authenticate', 'Basic realm=Users')

application = tornado.web.Application([
    (r"/users/(\w+)", UserHandler),
],debug=True)

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
于 2013-01-09T03:09:19.063 回答
1

您找到的解决方案(使用set_status()代替send_error())有效,因为send_error()调用clear()“[r] 设置所有标题和内容”,如源代码所示。write_error()然后它会根据状态代码调用以发送新的内容和标头。

如果您可以通过手动(或使用您自己的方法)设置所有内容和标题来处理错误,请不要使用send_error().

我发现你也可以修改RequestHandler's 方法来send_error()为你工作而不是反对你。标WWW-Authenticate头是任何401响应的预期部分,因此如果send_error(401)能自动添加它会很好。这可以通过覆盖来完成write_error()

class BaseHandler(RequestHandler):
    def write_error(self, status_code, **kwargs):
        if status_code == 401:
            self.add_header(
                'WWW-Authenticate',
                'Basic realm=' + json.dumps(self.realm))  # adds quotes
        super(BaseHandler, self).write_error(status_code, **kwargs)

class UserHandler(BaseHandler):
    realm = 'Users'
    # ...
于 2015-04-08T22:36:34.870 回答