Python 烧瓶:返回错误代码401.x

Python 烧瓶:返回错误代码401.x,python,flask,Python,Flask,我想通过从基于Flask的REST API返回错误代码401.1来通知我的客户登录失败 烧瓶可以用这样的东西: return {"message": "Invalid username or password"}, 401 如何返回HTTP401.1而不是401?您不能直接返回。烧瓶堆栈中使用的Werkzeug响应对象将始终将状态代码视为整数 这是因为HTTP RFC是: 状态代码元素是一个3位整数代码,用于描述 服务器试图理解并满足客户需求的结果 相应的请求 请在取消RFC之前,与客户一起检

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

烧瓶可以用这样的东西:

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

如何返回HTTP
401.1
而不是
401

您不能直接返回。烧瓶堆栈中使用的Werkzeug响应对象将始终将状态代码视为整数

这是因为HTTP RFC是:

状态代码元素是一个3位整数代码,用于描述 服务器试图理解并满足客户需求的结果 相应的请求

请在取消RFC之前,与客户一起检查您的要求

添加的
.x
子状态号是仅在服务器内部使用的。服务器发送401状态,但在日志中记录详细的子状态代码,并允许您根据子代码更改自定义错误消息。因此,最终用户在提供的错误页面中看到
401.1登录失败
,但状态行仍设置为
HTTP/1.1 401未经授权
。见:

请注意,在HTTP协议中没有401.1这样的东西 标题本身。(使用网络嗅探器查看以确认 你自己)

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

如果您必须发送这样的状态(并破坏RFC合规性),则必须对Flask使用的
响应
类进行子类化:

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
然后将该类用作
Flask()
对象上的
response\u class
属性:

from flask import Flask

app = Flask(...)
app.response_object = ResponseWithSubstatus
上述更改删除了
状态\u code
为整数的要求


请注意,您的WSGI服务器可能仍然会因此而阻塞!不同的WSGI服务器可能更好或更糟地处理不一致的状态行。

401.1是Microsoft的扩展;官方的HTTP RFC不允许这样的扩展,如果可以传播,它将取决于您的WSGI堆栈。为什么需要从Flask发送此信息?从:状态代码元素是一个3位整数代码,描述服务器试图理解并满足客户端相应请求的结果。@MartijnPieters,谢谢。客户需求中提到了错误代码。我在回答中已经说明了这一点,但我在这里重复:请与您的客户核实他们想要什么,真的。将状态代码设置为401.1会破坏RFC,只有您的服务器会这样做。IIS 401.1状态代码不是HTTP状态代码,只是一个内部代码,用于发送到日志,并便于向读取响应消息的任何人员提供自定义错误消息。这看起来很有希望。谢谢。@sisanared:注意,我目前找不到任何证据表明IIS确实在HTTP响应状态行中设置了子状态代码。看起来它只是一个内部代码,用于记录和选择更详细的错误消息。状态代码仍然是HTTP/1.0 401 Unauthorized
。您确定需要在状态行中设置此选项吗?@MartijnPieters“请注意,HTTP头本身没有401.1这样的选项。(使用网络嗅探器查看以自行确认)。当您在IE中看到401.1时,真正发生的是IIS在该HTTP结果中发送了HTTP/401错误代码,但正文文本提供了您看到的其他信息,声称它确实是401.1“@piotrdawiduk:感谢您的确认!微软自己的消息来源在这方面很有帮助。