我想通过从基于Flask的REST API返回错误代码401.1
来通知我的客户端登录失败。
Flask很好用这样的东西:
return {"message": "Invalid username or password"}, 401
如何返回HTTP 401.1
而不是401
?
答案 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服务器可以更好或更差地处理不符合的状态行。