BasicAuth提示不会显示状态401

时间:2013-01-09 02:38:19

标签: python http http-headers tornado basic-authentication

即使我使用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状态时,它确实显示在标题中,但它仍然没有显示密码提示。

2 个答案:

答案 0 :(得分: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()

答案 1 :(得分:1)

您找到的解决方案(使用set_status()代替send_error())有效,因为send_error()调用了clear(),其中“[设置了所有标题和内容”],在the source中可以看到。然后,它会根据状态代码调用write_error()发送新内容和标题。

如果您通过手动设置所有内容和标题(或使用您自己的方法)处理错误,那么就永远不要使用send_error()

我发现您还可以修改RequestHandler的方法,让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'
    # ...