While a 401 Unauthorized
may seem spiffy for these ("Access token is missing or invalid") it can throw many a client HTTP stack into prompting the user for credentials, something that won't succeed anyway since normal HTTP authentication mechanisms are not in play.
While I can detour that using another client library that I can direct not to attempt auto-auth or user prompting (and have done so) this seems to violate RFC 7235 as far as I can tell.
I suspect that a 403 Forbidden
would be more compliant here and less grief for API users. Most of them probably just see any non-2XX status and immediately run to look for a JSON "error" reponse body.
I have a detour so I'm not complaining, but something seems fishy here. Surely I'm missing something? Is it common practice now to use the 401
in this manner for REST-like HTTP APIs?
More detail
This works as long as the proper auth token is used, but causes a GUI prompt for user/pw if a bad token is used:
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
If the prompt is canceled by the user then the 401
gets reported to the code.
In light of information below I tried sending the auth token as a user ID value. However this raises a prompt even if the auth token is correct:
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
If the user manually enters the valid auth token into the prompt as the user ID the request then succeeds.
Based on new information below
This can be made to work by explictly sending a "."
as password:
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
Correct token value works, bad token value returns the 401
where it can be handled. No credentials prompt dialogs now.