8

Browser support issues aside, if you're being an Http/hateoas stickler what verbs should the request to log into/out of a site be?

DELETE would seem like the obvious choice but I'm not sure what the resource you're deleting would be.

2
  • You should make sure that any verb you choose is available on target platform. If you are targeting web browsers, not all browsers support all HTTP verbs.
    – grizwako
    May 3, 2013 at 9:58
  • 1
    @GrizzLy, that's true, this is more a question of theory as I couldn't readily think of what the correct answer was. May 3, 2013 at 20:23

3 Answers 3

10

HTTP is stateless, so you're never logging in/out of a website, those are just clever names we use for the cookie implementation.

What you actually do is GET an authentication token (cookie), after you POST authentication details. That your browser stores that cookie for you is just a convenience. Finally, after you're done with your authentication token, you POST that token to the server to let it know that it can be destroyed. Again, this all happens with cookies in the browser as a convenience.

If you want to be an HTTP stickler, your HTTP needs to be stateless (and maybe RESTful).

3
  • 1
    So to clarify, would you agree that Logout should be a client-side only operation (ie delete the cookie) after which the client should probably move to the entry point of the API? May 3, 2013 at 20:28
  • 1
    Yes and no. The client should inform the server that the session can be destroyed for security purposes. May 3, 2013 at 20:39
  • Even in a stateless API, you should render the access token as invalid/expired. You can log out of the client all you want but if you obtain the token that the client uses to access the API and it is still active/not expired then you can still use it.
    – ataraxia
    Aug 11, 2020 at 19:29
28

The common choice is POST, and it makes sense. The 'safe' verbs (GET, HEAD, OPTIONS, TRACE) are out, because they cannot have semantic side effects that change the observable state of the application (and logging in and out is such a state).

PUT and DELETE are theoretical possibilities; the resource you are creating (PUT) and removing (DELETE) would be the user's session. However, there are a few oddities about this: first of all, PUT and DELETE, while not safe like HEAD, are still supposed to be idempotent, that is, logging out several times in a row without logging back in would have to be valid, and so would logging in again while still logged in. Furthermore, such a double login cannot alter the state of the application beyond what the first login does, which, considering things like session IDs and such, is problematic. Also, strictly speaking, the URL you are PUTting to is supposed to uniquely identify the resource you are pushing, so in order to be semantically correct, you'd have to PUT to http://example.com/sessions/a8edjn239sd8h2er instead of http://example.com/login, that is, a unique identifier for the session would have to be encoded in the URL - but then, the session ID is generated along with the session, so the ID does not exist yet until after successful login.

The semantics of POST are a much better fit: your login URL (say, http://example.com/login) identifies a resource (the application's 'login functionality') that you are about to "annotate", that is, it changes an aspect of that resource. Unlike PUT and DELETE, POST requests do not have to be idempotent, which means multiple identical POST requests can continue to change the application state - this is exactly what you want.

Wikipedia's description of the various verbs is actually quite revealing in this regard:

https://en.wikipedia.org/wiki/HTTP_Verbs#Request_methods

5

Just want to clarify the accepted answer on how to logout, I use POST to a session resource (http://example.com/sessions/) for Login and the response includes a Location of the newly created session (http://example.com/sessions/a8edjn239sd8h2er).

For Logout, DELETE the session resource pointed by the Location from POST response.

You can Login/Logout multiple of times. Only first DELETE would return no content (204), after that it should return not found response (404). Logging in multiple times will create multiple sessions.

4
  • See, this is what I was thinking initially, but what would GET http://example.com/sessions/a8edjn239sd8h2er return? Worse, shouldn't GET ://example.com/products return the same thing whether or not you've previously POSTed to http://example.com/sessions/ or not? After some thought, I think @JonathanRich might have nailed it. May 3, 2013 at 20:27
  • 1
    @GeorgeMauer I do agree that HTTP is stateless. GET example.com/products still return the same thing, if you want it to return something. GET /products can also return unauthorized (401) if the client is not authenticated. I didn't want to go into the authentication details because there are too many different implementations. But, with I've used this method to return auth token with GET example.com/sessions/a8edjn239sd8h2er and set the token in Authorization header. This way clients don't need to have cookie (can be easier for non-browser apps).
    – imel96
    May 6, 2013 at 1:45
  • Ah, so you're saying you GET the auth token and then include that along as a parameter for all other requests? (Which I guess is what the cookie approach is already doing just using cookies) May 6, 2013 at 14:21
  • @GeorgeMauer yes, but include it as Authorization header, not parameter. This is also how it's done in basic authentication and OAuth. It is similar with cookie but people tend to make the application stateful when using cookie.
    – imel96
    May 6, 2013 at 23:13

Not the answer you're looking for? Browse other questions tagged or ask your own question.