Problem
The application expects the client to send the header Authorization with the access token on most of the routes. Now there is a new feature and some new few routes expect not only the Authorization header but also a pin attribute with a 6-length string inside the body of the request. If the pin value does not match the user's pin stored in the database, the request should be refused.
Which status code should be used to refuse the request since the user is authenticated (it sent a valid access token in the Authorization header) but sent a wrong pin value?
Context
This application will now support payments and the routes that need the pin attribute inside the body of the request are routes that make the payments, so they spend the user's credits inside the application. That's why it needs to send the pin only on a few routes.
Solutions I thought
- Use
422 Unprocessable Entitysince the request can not be processed because of the wrongpinvalue inside the body.- Problem: the status code
422is also sent when some other validation fails, so it doesn't seem right since thepinis more related to authorization.
- Problem: the status code
- Use
401 Not Authorizedsince a wrongpinvalue means the user failed to give all the proper credentials.- Problem: the user actually gave proper credentials for what the application expected on every route til now. The needed credentials to be considered authenticated in the application won't match after the new feature. The
401will now mean two kinds of errors instead of user is not authenticated only.
- Problem: the user actually gave proper credentials for what the application expected on every route til now. The needed credentials to be considered authenticated in the application won't match after the new feature. The
- Use
403 Forbidden.- Problem: although the user is not allowed, this is not a matter of role permissions.
Extra question: is it better for the pin to be sent in the headers instead of the body?
I think 422, 403 and 400 are all 'ok enough'. I would probably go for 400 because it is a bit more of a unique situation, and none of the status codes IMHO fit perfectly.