访问令牌错误时返回 401 状态
401 Status Returned on Access Token Errors
虽然 401 Unauthorized
对于这些(“访问令牌丢失或无效”)可能看起来很漂亮,但它可以抛出许多客户端 HTTP 堆栈来提示用户输入凭据,这无论如何都不会成功,因为正常的 HTTP 身份验证机制不起作用。
虽然我可以使用另一个客户端库来绕过它,但我可以指示它不要尝试自动身份验证或用户提示(并且已经这样做了),据我所知,这似乎违反了 RFC 7235。
我怀疑 403 Forbidden
在这里会更合规,并且对 API 用户来说会更少悲伤。他们中的大多数人可能只是看到任何非 2XX 状态并立即 运行 寻找 JSON“错误”响应正文。
我走了弯路所以我没有抱怨,但这里似乎有些可疑。当然我错过了什么?现在以这种方式将 401
用于类似 REST 的 HTTP APIs 是常见的做法吗?
更多详情
只要使用正确的身份验证令牌,它就可以工作,但如果使用了错误的令牌,则会导致 GUI 提示 user/pw:
Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a deep copy of template JSON.
With JsonBag
.Item("title") = txtTitle.Text
.Item("body") = txtBody.Text
End With
With XMLHTTP
.abort 'Clean up previously failed request if any.
.open "POST", PBConfig.Item("CreatePushUrl"), True
.setRequestHeader "Access-Token", PBConfig.Item("AccessToken")
.setRequestHeader "Content-Type", "application/json"
.onreadystatechange = SinkRSChange
.send JsonBag.JSON
End With
如果提示被用户取消,则 401
会报告给代码。
根据以下信息,我尝试将身份验证令牌作为用户 ID 值发送。然而,即使身份验证令牌正确,这也会引发提示:
Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a deep copy of template JSON.
With JsonBag
.Item("title") = txtTitle.Text
.Item("body") = txtBody.Text
End With
With XMLHTTP
.abort 'Clean up previously failed request if any.
.open "POST", PBConfig.Item("CreatePushUrl"), True, PBConfig.Item("AccessToken")
.setRequestHeader "Content-Type", "application/json"
.onreadystatechange = SinkRSChange
.send JsonBag.JSON
End With
如果用户在提示中手动输入有效的身份验证令牌作为用户 ID,则请求成功。
根据以下新信息
这可以通过明确发送 "."
作为密码来实现:
Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a deep copy of template JSON.
With JsonBag
.Item("title") = txtTitle.Text
.Item("body") = txtBody.Text
End With
With XMLHTTP
.abort 'Clean up previously failed request if any.
.open "POST", PBConfig.Item("CreatePushUrl"), True, PBConfig.Item("AccessToken"), "."
.setRequestHeader "Content-Type", "application/json"
.onreadystatechange = SinkRSChange
.send JsonBag.JSON
End With
正确的令牌值有效,错误的令牌值 returns 401
可以处理。现在没有凭据提示对话框。
从技术上讲,正常的 HTTP 身份验证机制正在发挥作用。 api 甚至要求您的浏览器提供凭据,以便您可以在浏览器中执行请求(实际上有人请求了)。
对 401 具有特殊行为的 HTTP 库似乎确实是个问题,但有一次它发生了,我能够禁用神奇的 401 处理。我不知道谁在这里违反了 RFC 7235。 RFC 2616 10.4.2 似乎表明当前行为是 "correct"。您是否有提示用户输入凭据的 HTTP 客户端列表?
也许 403 在这里更有意义,但 Stripe 至少似乎使用了 401:https://stripe.com/docs/api#errors 而且它们都是关于 REST 的。切换到 403 也会破坏所有现有客户端。大多数客户端实际上并没有足够奇怪地查看 JSON 主体,他们只是查看状态代码。
我认为如果我创建另一个 HTTP API,它将只有 200/400/500 个状态代码,其中 POST 个 JSON 编码主体和 JSON 响应。
选择:
如果不需要支持 Windows 的下级版本,您可以使用 WinHttp.WinHttpRequest 对象替代上述问题示例中使用的 MSXML2.XMLHTTP 对象。
Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a copy.
JsonBag("title") = txtTitle.Text
JsonBag("body") = txtBody.Text
With WinHttp
.Abort 'Clean up previously failed request if any.
.Open "POST", PBConfig("CreatePushUrl"), True
.SetAutoLogonPolicy AutoLogonPolicy_Never
.SetRequestHeader "Access-Token", PBConfig("AccessToken")
.SetRequestHeader "Content-Type", "application/json"
.Send JsonBag.JSON
End With
关键是 .SetAutoLogonPolicy AutoLogonPolicy_Never
我们没有旧版 class。
请注意,此示例利用了一个事实,即 JsonBag 将 .Item()
作为其默认值 属性...那些。它与 WinHttp 的使用无关,也可以在早期的代码片段中以这种方式编写。
虽然 401 Unauthorized
对于这些(“访问令牌丢失或无效”)可能看起来很漂亮,但它可以抛出许多客户端 HTTP 堆栈来提示用户输入凭据,这无论如何都不会成功,因为正常的 HTTP 身份验证机制不起作用。
虽然我可以使用另一个客户端库来绕过它,但我可以指示它不要尝试自动身份验证或用户提示(并且已经这样做了),据我所知,这似乎违反了 RFC 7235。
我怀疑 403 Forbidden
在这里会更合规,并且对 API 用户来说会更少悲伤。他们中的大多数人可能只是看到任何非 2XX 状态并立即 运行 寻找 JSON“错误”响应正文。
我走了弯路所以我没有抱怨,但这里似乎有些可疑。当然我错过了什么?现在以这种方式将 401
用于类似 REST 的 HTTP APIs 是常见的做法吗?
更多详情
只要使用正确的身份验证令牌,它就可以工作,但如果使用了错误的令牌,则会导致 GUI 提示 user/pw:
Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a deep copy of template JSON.
With JsonBag
.Item("title") = txtTitle.Text
.Item("body") = txtBody.Text
End With
With XMLHTTP
.abort 'Clean up previously failed request if any.
.open "POST", PBConfig.Item("CreatePushUrl"), True
.setRequestHeader "Access-Token", PBConfig.Item("AccessToken")
.setRequestHeader "Content-Type", "application/json"
.onreadystatechange = SinkRSChange
.send JsonBag.JSON
End With
如果提示被用户取消,则 401
会报告给代码。
根据以下信息,我尝试将身份验证令牌作为用户 ID 值发送。然而,即使身份验证令牌正确,这也会引发提示:
Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a deep copy of template JSON.
With JsonBag
.Item("title") = txtTitle.Text
.Item("body") = txtBody.Text
End With
With XMLHTTP
.abort 'Clean up previously failed request if any.
.open "POST", PBConfig.Item("CreatePushUrl"), True, PBConfig.Item("AccessToken")
.setRequestHeader "Content-Type", "application/json"
.onreadystatechange = SinkRSChange
.send JsonBag.JSON
End With
如果用户在提示中手动输入有效的身份验证令牌作为用户 ID,则请求成功。
根据以下新信息
这可以通过明确发送 "."
作为密码来实现:
Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a deep copy of template JSON.
With JsonBag
.Item("title") = txtTitle.Text
.Item("body") = txtBody.Text
End With
With XMLHTTP
.abort 'Clean up previously failed request if any.
.open "POST", PBConfig.Item("CreatePushUrl"), True, PBConfig.Item("AccessToken"), "."
.setRequestHeader "Content-Type", "application/json"
.onreadystatechange = SinkRSChange
.send JsonBag.JSON
End With
正确的令牌值有效,错误的令牌值 returns 401
可以处理。现在没有凭据提示对话框。
从技术上讲,正常的 HTTP 身份验证机制正在发挥作用。 api 甚至要求您的浏览器提供凭据,以便您可以在浏览器中执行请求(实际上有人请求了)。
对 401 具有特殊行为的 HTTP 库似乎确实是个问题,但有一次它发生了,我能够禁用神奇的 401 处理。我不知道谁在这里违反了 RFC 7235。 RFC 2616 10.4.2 似乎表明当前行为是 "correct"。您是否有提示用户输入凭据的 HTTP 客户端列表?
也许 403 在这里更有意义,但 Stripe 至少似乎使用了 401:https://stripe.com/docs/api#errors 而且它们都是关于 REST 的。切换到 403 也会破坏所有现有客户端。大多数客户端实际上并没有足够奇怪地查看 JSON 主体,他们只是查看状态代码。
我认为如果我创建另一个 HTTP API,它将只有 200/400/500 个状态代码,其中 POST 个 JSON 编码主体和 JSON 响应。
选择:
如果不需要支持 Windows 的下级版本,您可以使用 WinHttp.WinHttpRequest 对象替代上述问题示例中使用的 MSXML2.XMLHTTP 对象。
Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a copy.
JsonBag("title") = txtTitle.Text
JsonBag("body") = txtBody.Text
With WinHttp
.Abort 'Clean up previously failed request if any.
.Open "POST", PBConfig("CreatePushUrl"), True
.SetAutoLogonPolicy AutoLogonPolicy_Never
.SetRequestHeader "Access-Token", PBConfig("AccessToken")
.SetRequestHeader "Content-Type", "application/json"
.Send JsonBag.JSON
End With
关键是 .SetAutoLogonPolicy AutoLogonPolicy_Never
我们没有旧版 class。
请注意,此示例利用了一个事实,即 JsonBag 将 .Item()
作为其默认值 属性...那些。它与 WinHttp 的使用无关,也可以在早期的代码片段中以这种方式编写。