To begin with, authentication is often performed outside of the REST model. When a user provides their credentials, they do not provide a REpresentation of their STAT account object (REST); as well as the answer they receive in this way. Since the resource state of a user account does not include both “current” and “new” passwords, providing both a “current” and a “new” password in a request can never truly match the REST model, but professionals often describe the “continuum” of RESTfulness, with some APIs being completely RESTful, while others are RPC (Remote Procedure Call) and REST.
Often there is a RESTful API component that processes data model services, and more often an RPC API component that processes user accounts. You can decide between them. If your project includes superusers who manage multiple user accounts, I would suggest trying a shoehorn in the REST API. If each user only manages his account, I would suggest RPC.
If you decide to use REST for account management, you must select the appropriate HTTP method (GET, POST, DELETE, HEADERS, etc.). Obviously, you need a method that will affect the change on the server (POST, PUT, DELETE, etc.). Unlike the orbfish output above, I'm going to say that PUT would be a suitable method under certain restrictions.
From RFC 2616 , which formally defines our HTTP methods:
“Methods may also have the“ idempotence ”property in that (in addition to errors or expiration errors) the side effects of N> 0 of the same requests are the same as for one request. The GET, HEAD, PUT and DELETE methods share this property. In addition , the OPTIONS and TRACE methods SHOULD NOT have side effects, and therefore are inherently idempotent. "
Idempotency here means that if we make the same request n times in a row, the state of the server under the action of the nth request will be the same as the state of the server under the action of the first request. The orbfish user correctly points out that if we make a request:
PUT /users/:id/account {current-password: 'a', new-password: 'b'}
and repeat it:
PUT /users/:id/account {current-password: 'a', new-password: 'b'}
for our first request to receive a response indicating success, and our second request should receive a response indicating failure. However, the idempotency of PUT only requires that the server state be the same after both requests. And this: after the first request, the password for user "b", and after the second request, the password for user "b".
I mentioned the above limitations. You might want to block the user after m tries to change the password unsuccessfully; this will provide protection against brute force password attacks. However, this will violate the idempotency of the request: send a valid password request once, and you will change your password, send it again and the server will block you.
By specifying the PUT method, you tell all clients that it is safe to send the request as many times as necessary. If I send a PUT request as a client, and our connection is interrupted so that I do not receive your answer, I know that it is safe to send my PUT again, because it is idempotent: idempotency means that if you receive both requests, it will be the same like on your server, just getting it. But if you are going to block me for an unsuccessful request, then it is unsafe to send a second request until I find out if you received the first.
For this reason, you may consider PATCH or POST. I would suggest using PATCH. While POST is described as adding a new resource to a list or adding data to an existing resource, PATCH is described as a “partial update” of a resource in a known URI. And unlike PUT, PATCH need not be idempotent.