11

im thinking what is the best RESTful way how confirm email and request reseting password. Im only aiming to find correct URI...

confirm email

PUT /users/{userId}/confirmEmail?code=xyz - does not seem much RESTful because of confirmEmail

PUT /users/{userId}/email?confirmedBy=xyz - maybe better? dunno

reset password (similar problem)

PUT /users/{userId}/resetPassword --DATA {email:xyz@xyz.xy} - same thinkin as before

PUT /users/{userId}/password --DATA {state:reseted,resent:xyz@xyz.xy} - hmmm... again Im not sure

are there any better ways in your mind?:-)

dxxx
  • 211
  • 1
  • 3
  • 9
  • 2
    Why use `PUT` and not `POST`? You're not really setting a new representation for the resource you're addressing (and it's not necessarily idempotent either). – Bruno Jul 12 '11 at 12:35
  • yes ok, could be POST I agree. But Im aiming for URI.. – dxxx Jul 12 '11 at 12:40
  • If you want to do it the REST way, the URI structure should be secondary to the hypermedia (the way you tell the client what to do with this URI). URIs are meant to be opaque and their structure is about how you implement the action internally. You may be interested in these links: http://stackoverflow.com/questions/3889099/give-me-a-example-of-non-restful-design/3889341#3889341 and http://stackoverflow.com/questions/4044391/rest-get-verb-with-parameters/4044656#4044656 – Bruno Jul 12 '11 at 12:47

7 Answers7

10

If you want your URIs to refer to resources, then call the resource confirmation and POST confirmations to user accounts.

POST /users/{userid}/confirmation
Carles Barrobés
  • 10,995
  • 4
  • 40
  • 60
5

The true RESTful answer is the URL does not matter, you put it in the confirmation e-mail anyway for the recipient to follow. Use whatever is most convenient for your load balancer, reverse proxy, servers, etc.

For convenience you'll end up accepting the confirmation even if it comes in a GET request, because that's what the browsers of flesh-and-bones humans oblivious to Dr Roy T. Fielding et al. send when clicking on a link in an e-mail :-)

Having established it is completely academic, I'd argue you were right to think of PUT, as the client idempotently places evidence of having access to the e-mail. Repeating the request has no further effect.

Szocske
  • 6,750
  • 2
  • 18
  • 24
  • From a technical standpoint, URL structure really doesn't matter to having a request process successfully. From an ease-of-understanding, API discovery and maintainability perspective, they make a massive difference. Trying to argue URL structure doesn't matter is like arguing that the names of classes doesn't matter. – Paul Turner Jul 13 '11 at 14:29
  • 3
    Yupp, I think we are saying the same thing, just as Class names do not matter to the JVM, you are free to chose them at the comfort of the programmers. API discovery in this case is receiving the e-mail, a human recognizing there's a confirmation link in there, and clicking it :-) – Szocske Jul 13 '11 at 16:56
2

Considering that he said a reset service for someone who forgot her password, and not a change password service for someone already logged in...

I would use 2 services. 1st to request the reset password mail, and 2nd to set the new password with the token received in the received mail.

For the 1st:
POST baseUrl/passwordReset
Request body

{
   "email" : "my@self.com"
}

This could be POST or PUT, but since a mail delivery is not a resource subject to CRUD anyway, let's not be pedantic and use the old POST that was always used in html forms.

Obviously I would control that the same client (ip? browser? ...) doesn't make me send 20K mails in a minute.

Sending the mail to the user doesn't imply that the old password is not valid. That will only happen later in the second request when the new one updates it.

Response 204 (perhaps you should do it even if you don't know that email, because if you return error that means that when you don't return error you are confirming to a stranger that the given email is registered)

For the 2nd:
POST baseUrl/password
Request body

{
    "token" : "3D21BA...4F",
    "newPassword" : "m%4pW1!O"
}

Where the token is received in the mail. So the mail could have a link to a page including the token, when the page is loaded, the form is filled and submitted, being the token a hidden field that some javascript reads from the URL and puts here.

This is really a resource that you update, so POST. And I don't think it makes sense to have the same URI with 2 verbs for both, because they are not the same resource/entity at all.

Add By the way, I would make both HTTPS only, and that's why I put all the sensitive information in the body, not URL parameters.

antonio.fornie
  • 1,690
  • 2
  • 13
  • 21
1

Firstly, I don't think that PUT is the right method for this. PUT broadly means "put this here", where the URL is identifying where the content should be located. You're really asking an existing resource to perform some action, which makes POST more correct.

To answer your direct question, a RESTful URL should identify the resource you want to handle your request. In this case, the resource is either the user, or some password-resetting resource within the user.

My preference would be for a password-resetting resource:

POST /users/{userid}/password-reset

This makes sense from a HTTP point of view, since you could issue a GET on the resource and receive something which indicates how to action a password reset (e.g. a HTML form prompting for the email address of the associated account).

EDIT:

For the purposes of email validation, there are two obvious options. You could either POST to a "confirm email" resource with the email address and confirmation data, to ask the server to process the confirmation, or you can execute a PUT to put the confirmation information on the server:

POST /users/{userid}/confirm-email

or

PUT /users/{userid}/email-confirmation

Paul Turner
  • 35,361
  • 15
  • 90
  • 155
  • I commented POST in previous post, I agree. Nvm, let's identify as password-reset resource. Then i guess you would add similary email-confirm resource? And adding query parameter or data for code? – dxxx Jul 12 '11 at 12:54
  • When you say "confirm email" what do you mean exactly? What part of the process requires the user to confirm their email? The question could do to be edited to include your use case. – Paul Turner Jul 12 '11 at 13:48
  • thats kinda classic stuff after registration. You register, then you recieve email with confirmation code which u send to server and ur email is now treated as confirmed. – dxxx Jul 12 '11 at 13:53
  • The limitation here will be your email client: it probably will only do HTTP GET operations, which is not RESTful for this action; GET should only retrieve a representation of a resource and should not have side-effects (like updating a user's account). I think you'll have to break away the RESTful model to achieve what you want. – Paul Turner Jul 13 '11 at 08:49
  • Yep I was thinking of that. And I wont have to do it bad. The RESTful interface is used for contacting application logic. This interface is called by web front-end. So I will create some GET URL to front-end, there will be some form with filled code (from email) and by submitting this form, the web app will call REST API and it doesnt matter what method it calls (it can call anything) – dxxx Jul 13 '11 at 11:52
  • Updated my answer with something more relevant to your proposed flow. – Paul Turner Jul 13 '11 at 14:21
1

Here is a RESTful way.

Request

PUT /{userid}/email HTTP/1.1
Content-Type: text/json+confirmation-code

{"activateCode": "23sfgsg3twt3rgsdhgs"}

Response

HTTP/1.1 200 OK
Content-Type: text/json+email-status
{"email": "my-email@address.com", "active": "true"}

No verbs in the URI needed :)

Malachi
  • 30,486
  • 16
  • 60
  • 96
Michael Brown
  • 498
  • 4
  • 13
0

I've recently worked on this, my take was

POST /{base_url}/password

because I was actually creating a new random password and sending it over to the user

and

PUT /{base_url}/confirmation?token=...

Because I am updating the confirmation that was already sent out when the user registered.

Calin
  • 6,042
  • 5
  • 42
  • 74
0

I don't really see anything wrong with having confirmEmail like the 1st example. In the URL you have the key to the user, confirmEmail is the action, and the data with that action is in the query string.

Tim Almond
  • 9,812
  • 10
  • 37
  • 50
  • well, as far as I know. Doing RESTful interface is always a compromise, but you should be looking on URI as on the way in the graph. Adding an action into the URI is imho not RESTful. This URI tells me, between users, find specified user and his confirmEmail, strange... – dxxx Jul 12 '11 at 12:41
  • @dxxx, there's nothing wrong with putting an action name in the URI, so long as getting the representation at that URI doesn't actually perform that action (but provides you with a form telling the client how to do this action, for example). (Similar to [this answer](http://stackoverflow.com/questions/3889099/give-me-a-example-of-non-restful-design/3889341#3889341).) – Bruno Jul 12 '11 at 12:49
  • well I was learned not to do that, thats why im trying to find another way. I know that resource != model. That resource is just something different than object with attributes. But still having an action within URI seems... I dont know..., just bad feelind:-) – dxxx Jul 12 '11 at 13:02
  • Call it confirmationEmail if the verb orientation of the word confirm doesn't sit well with you. – laz Jul 12 '11 at 20:45