Short answer
If the token is part of the body of the request, 403 (or 404), but is sent as token authentication, 401.
400 Bad Request
I definitely wouldn’t go with an answer 400: Bad Request. This error indicates that the request failed due to errors in the client, which generated a request that was not understood in its integrity by the server. If you like to impersonate things, it would be as if the server responded:
— My dear, I have received your request, but I do not understand what you are requesting, so I will not deliver any content in order to avoid misunderstandings.
But in my opinion, the request would be correct - within the context addressed in the question -, only the token that would no longer be valid.
The 400 (Bad Request) status code indicates that the server cannot
or will not process the request due to Something that is Perceived
to be a client error (e.g., malformed request syntax, invalid
request message Framing, or deceptive request routing).
403 Forbidden
I believe the answer 403: Forbidden makes more sense here, because it indicates that the server understood what the request was, but did not generate the payload expected, that is, did not effect the request, due to inconsistent data. In addition, the server will be explicitly informing the client not to try again with the same data and, if it really needs to take action, it should update the data sent.
— My dear fellow, I understand what you have requested, but unfortunately I cannot process your request because something is not right. Please check the information you gave me.
The 403 (Forbidden) status code indicates that the server
understood the request but refuses to Authorize it. A server that
Wishes to make public Why the request has been Forbidden can
describe that Reason in the Response payload (if any).
If Authentication credentials Were provided in the request, the server considers them insufficient to Grant access. The client SHOULD NOT Automatically repeat the request with the same credentials. The client MAY repeat the request with new or Different credentials. However, a request Might be Forbidden for reasons unrelated to the credentials.
An origin server that Wishes to "Hide" the Current Existence of a Forbidden target Resource MAY Instead Respond with a status code of 404 (Not Found).
404 Not Found
And, as RFC comments, depending on your application requirements, you may not want to expose its architecture in a failed request. If you don’t want to expose that the password recovery feature exists in this URL, you can return the answer 404: Not Found which, in my view, can be interpreted in two ways, depending on the origin of the request. If the request came from your own application, which knows for sure that the password recovery feature exists in this URL, you can interpret the 404 answer as "token not localized, "which is true, for if he expired he, ideally, no longer exists. Already, if the request starts, for example, from a malicious user trying to modify the password of other users, the 404 response may confuse you thinking that the resource does not exist in this URL.
409 Conflict
The answer 409: Conflict I also think it doesn’t fit here, as it is usually associated with updating a resource that has been modified by other sources in the process. Something like: I searched a record for editing and while making the necessary changes, another user changes the record. The original information that was the basis for my amendments is no longer the persistent information in the resource, which can/should generate conflict informing me that the resource has been updated and that I should review my changes. Similar case when two users change the same disk file.
401 Unauthorized
Also, if you use the token as a form of authentication of the customer, the answer 401: Unauthorized is an option. For example, to display the password recovery form you do:
GET /esqueci-minha-senha HTTP/1.1
Authorization: Basic e8d95a51f3af4a3b134bf6bb680a213a
And the token authentication is not valid, the 401 response will be acceptable. As commented on in other responses, there is the requirement in the specification that a 401 response must include the header WWW-Authenticate
containing a defiance.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="ForgotPassword"
There is a description in Challenge-Sponse Authentication on defining the challenge:
In security protocols, a Challenge is some data sent to the client by
the server in order to generate a Different Response each time.
Challenge-Response protocols are one way to Fight Against replay
Attacks Where an Attacker Listens to the Previous messages and resends
them at a later time to get the same credentials as the original
message.
The HTTP Authentication Protocol is Challenge-Response based, though
the "Basic" Protocol isn’t using a real Challenge (the Realm is Always
the same).
However, if the token recovery is sent as part of the body of the request, I see no sense in returning to 401, but rather to 403 (or 404, as mentioned above).
498 Invalid Token
Regarding the use of non-standard codes, such as 498: Invalid Token I would judge valid only when your application interacts only with other applications of yours or of very well documented third parties, which make explicit that they expect or support such responses. Browsers do not qualify as such, so I think it is risky to return to it an answer outside the specifications, even because it runs the risk of each browser interpreting in a different way. If your server has, for example, a gateway entry, I find it perfectly valid to use whatever the answer, even those not provided for by RFC, provided that the gateway know how to solve such responses to one within the specifications.
No cat was mistreated during the drafting of this reply.
Those who have denied the question could clarify how the question can be improved?
– Wallace Maxters
Thinking so, "400 seems to be more related to an invalid parameter.". If we look at the lifetime of the token as a parameter, it could very well be a bad request.
– MarceloBoni
@Marceloboni URL [or form] parameter, I meant. That is, I would usually use the 400 to indicate that the guy stopped putting the parameter
id
url, which would be required to generate a PDF, for example.– Wallace Maxters
Just commenting, Inkedin a few years ago issued a code
HTTP 999
when we tried to access public data without using their API, of course they changed that today, but I found it very creative, basically a joke with those who didn’t use the xD API (details: https://stackoverflow.com/a/27571486/1518921)– Guilherme Nascimento