Flask:返回错误代码401.x.

时间:2017-02-09 08:12:22

标签: python flask

我想通过从基于Flask的REST API返回错误代码401.1来通知我的客户端登录失败。

Flask很好用这样的东西:

return {"message": "Invalid username or password"}, 401

如何返回HTTP 401.1而不是401

1 个答案:

答案 0 :(得分:2)

你无法开箱即用。 Flask堆栈中使用的Werkzeug响应对象将始终将状态代码视为整数。

那是因为HTTP RFC是very clear on what values are permitted for a status code

  

status-code元素是一个描述的3位整数代码      服务器尝试理解和满足客户端的结果      相应的要求。

在破坏RFC之前,请检查您的客户的要求。

添加.x子状态编号是Microsoft IIS extension,仅在内部使用 。服务器发送401状态,但在日志中记录详细信息子代码,并允许您根据子代码更改自定义错误消息。因此,最终用户会在提供的错误页面中看到401.1 Logon failed,但状态行仍设置为HTTP/1.1 401 Unauthorized。见this post by a Microsoft engineer

  

请注意,在HTTP方面没有401.1这样的东西   标题本身。 (观看使用网络嗅探器进行确认   自己)。

     

当你在IE中看到401.1时,真正发生的是IIS正在发送   关闭该HTTP结果中的HTTP / 401错误代码,但正文提供   您看到的其他信息声称它真的是401.1

如果绝对必须发送此类状态(并违反RFC合规性),则必须继承Flask使用的Response类:

from flask import Response
from werkzeug.http import HTTP_STATUS_CODES

class ResponseWithSubstatus(Response):
    @property
    def status_code(self):
        """The HTTP Status code as number"""
        return self._status_code

    @status_code.setter
    def status_code(self, code):
        self._status_code = code
        try:
            main_code = code
            if isinstance(code, str) and '.' in code:
                main_code = int(code.partition('.')[0])
            self._status = '%s %s' % (code,    
                HTTP_STATUS_CODES[main_code].upper())
        except (ValueError, KeyError):
            self._status = '%s UNKNOWN' % code

    @property
    def status(self):
        """The HTTP Status code"""
        return self._status

    @status.setter
    def status(self, value):
        self._status = value
        self._status_code = self._status.split(None, 1)[0]
        try:
            self._status_code = int(self.status_code)
        except ValueError:
            pass

然后将该类用作response_class对象的Flask()属性:

from flask import Flask

app = Flask(...)
app.response_object = ResponseWithSubstatus

上述更改删除了status_code为整数的要求。

请注意,您的WSGI服务器仍有可能阻塞此操作!不同的WSGI服务器可以更好或更差地处理不符合的状态行。