0

虽然401 Unauthorized这些看起来很漂亮(“访问令牌丢失或无效”),但它可以抛出许多客户端 HTTP 堆栈来提示用户输入凭据,这无论如何都不会成功,因为正常的 HTTP 身份验证机制不起作用。

虽然我可以绕道使用另一个我可以指示不要尝试自动身份验证或用户提示(并且已经这样做)的客户端库,但据我所知,这似乎违反了RFC 7235 。

我怀疑 a403 Forbidden在这里会更合规,对 API 用户的痛苦更少。他们中的大多数可能只是看到任何非 2XX 状态并立即运行以查找 JSON“错误”响应体。

我绕道而行,所以我没有抱怨,但这里似乎有些可疑。我肯定错过了什么吗?现在以401这种方式将 REST 用于类似 REST 的 HTTP API 是一种常见的做法吗?

更多详情

只要使用了正确的身份验证令牌,这就会起作用,但如果使用了错误的令牌,则会导致用户/密码的 GUI 提示:

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

正确的令牌值有效,错误的令牌值返回401可以处理的位置。现在没有凭据提示对话框。

4

2 回答 2

0

正常的 HTTP 身份验证机制在技术上正在发挥作用。该 api 甚至会向您的浏览器询问凭据,以便您可以在浏览器中执行请求(实际上是有人请求的)。

对 401 有特殊行为的 HTTP 库似乎确实是个问题,但有一次我能够禁用魔法 401 处理。我不知道谁在这里违反了 RFC 7235。RFC 2616 10.4.2 似乎表明当前行为是“正确的”。您是否有提示用户输入凭据的 HTTP 客户端列表?

也许 403 在这里更有意义,但 Stripe 至少似乎使用了 401:https ://stripe.com/docs/api#errors ,它们都是关于 REST 的。切换到 403 也会破坏所有现有的客户端。大多数客户端实际上并不奇怪地查看 JSON 正文,他们只查看状态代码。

我想如果我制作另一个 HTTP API,它将只有 200/400/500 个状态代码,其中包含 JSON 编码主体的 POST 和 JSON 响应。

于 2015-10-03T07:25:14.897 回答
0

选择:

如果不需要支持 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我们没有旧课程可用的。

请注意,此示例利用了 JsonBag.Item()作为其默认属性这一事实……以防万一您想知道此代码片段与以前的代码片段相比有何不同。它与 WinHttp 的使用无关,并且在早期的代码片段中也可以这样编写。

于 2015-10-04T06:27:59.313 回答