views:

1851

answers:

5

Disclaimer: I'm new to the REST school of thought, and I'm trying to wrap my mind around it.

So, I'm reading this page, Common REST Mistakes, and I've found I'm completely baffled by the section on sessions being irrelevant. This is what the page says:

"There should be no need for a client to "login" or "start a connection." HTTP authentication is done automatically on every message. Client applications are consumers of resources, not services. Therefore there is nothing to log in to! Let's say that you are booking a flight on a REST web service. You don't create a new "session" connection to the service. Rather you ask the "itinerary creator object" to create you a new itinerary. You can start filling in the blanks but then get some totally different component elsewhere on the web to fill in some other blanks. There is no session so there is no problem of migrating session state between clients. There is also no issue of "session affinity" in the server (though there are still load balancing issues to continue)."

Okay, I get that HTTP authentication is done automatically on every message - but how? Is the username/password sent with every request? Doesn't that just increase attack surface area? I feel like I'm missing part of the puzzle.

Would it be bad to have a REST service, say, /session, that accepts a GET request, where you'd pass in a username/password as part of the request, and returns a session token if the authentication was successful, that could be then passed along with subsequent requests? Does that make sense from a REST point of view, or is that missing the point?

+6  A: 

It is not uncommon for a REST service to require authentication for every HTTP request. For example, Amazon S3 requires that every request have a signature that is derived from the user credentials, the exact request to perform, and the current time. This signature is easy to calculate on the client side, can be quickly verified by the server, and is of limited use to an attacker who intercepts it (since it is based on the current time).

Greg Hewgill
I love this approach. Will start using it right away.
Thomas Ahle
+12  A: 

To be RESTful, each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP.

Okay, I get that HTTP authentication is done automatically on every message - but how?

Yes, the username and password is sent with every request. The common methods to do so are basic access authentication and digest access authentication. And yes, an eavesdropper can capture the user's credentials. One would thus encrypt all data sent and received using Transport Layer Security (TLS).

Would it be bad to have a REST service, say, /session, that accepts a GET request, where you'd pass in a username/password as part of the request, and returns a session token if the authentication was successful, that could be then passed along with subsequent requests? Does that make sense from a REST point of view, or is that missing the point?

This would not be RESTful since it carries state but it is however quite common since it's a convenience for users; a user does not have to login each time.

What you describe in a "session token" is commonly referred to as a login cookie. For instance, if you try to login to your Yahoo! account there's a checkbox that says "keep me logged in for 2 weeks". This is essentially saying (in your words) "keep my session token alive for 2 weeks if I login successfully." Web browsers will send such login cookies (and possibly others) with each HTTP request you ask it to make for you.

z8000
+1  A: 

I think your suggestion is OK, if you want to control the client session life time. I think that RESTful architecture encourages you to develop stateless applications. As @2pence wrote "each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP" .

However, not always that is the case, sometimes the application needs to tell when client logs-in or logs-out and to maintain resources such as locks or licenses based on this information. See my follow up question for an example of such case.

LiorH
+2  A: 

Okay, I get that HTTP authentication is done automatically on every message - but how?

"Authorization:" HTTP header send by client. Either basic (plain text) or digest.

Would it be bad to have a REST service, say, /session, that accepts a GET request, where you'd pass in a username/password as part of the request, and returns a session token if the authentication was successful, that could be then passed along with subsequent requests? Does that make sense from a REST point of view, or is that missing the point?

The whole idea of session is to make stateful applications using stateless protocol (HTTP) and dumb client (web browser), by maintaining the state on server's side. One of the REST principles is "Every resource is uniquely addressable using a universal syntax for use in hypermedia links". Session variables are something that cannot be accessed via URI. Truly RESTful application would maintain state on client's side, sending all the necessary variables over by HTTP, preferably in the URI.

Example: search with pagination. You'd have URL in form

http://server/search/urlencoded-search-terms/page_num

It's has a lot in common with bookmarkable URLs

vartec
Authentication information is not accessable via URI either, though - everyone is talking about sending auth info as part of the request header. How is that different from including a session token with the request? I'm not saying use the session token in the URI, but in data passed in the request.
unforgiven3
Authentication establishes if you're authorized to execute that action, and in RESTful application would not affect it's result.
vartec
A session token also establishes if you're authorized to execute that action. What do you mean it wouldn't affect it's result? If the caller is not authorized, they get a Not Authorized error. Same thing with a session token. I really don't see the difference?
unforgiven3
No, session token is a handle to **state** saved on the server. That's just not RESTful. As for the Not Authorized, I don't see that as a result. I'd rather consider that an exception (as in try/catch).
vartec
Fair enough, vartec - that makes sense. Thanks for the follow-up!
unforgiven3
That was a good explanation, Vartec
Flubba
+2  A: 

No, it doesn't miss the point. Google's ClientLogin works in exactly this way with the notable exception that the client is instructed to go to the "/session" using a HTTP 401 response. But this doesn't create a session, it only creates a way for clients to (temporarily) authenticate themselves without passing the credentials in the clear, and for the server to control the validity of these temporary credentials as it sees fit.

mogsie
That doesn't seem RESTful, though.
unforgiven3
@unforgiven3 As long as the returned token is only used to authenticate the user and not used by the server to associate the user to other state stored on the server, then I see no REST constraints being violated.
Darrel Miller
@Darrel, how could subsequent HTTP requests be authenticated? My understanding is authentication happens on every HTTP requests.
unforgiven3
@unforgiven3 The token returned by the server is, in effect, proof the user is who they say they are. So, instead of each request including user name and password, each request includes the token which is constructed in such a way that the server can be confident of its veracity.
Darrel Miller
@unforgiven3 Unfortunately, I can't tell you how to construct that token. I don't have nearly enough knowledge of security to be able to do that. I'm sure there are some standards out there for this, I just haven't gone looking yet.
Darrel Miller
@unforgiven3, Darrel is right. The token echoed back would have to be sent by the client on every HTTP request, just like in basic, digest authentication, until the token expires. When that happens the client can repeat the login, optionally asking the user for credentials, or whatever. I could elaborate the answer, if you want. **edit:** (And thanks for keeping up with answers to old questions!)
mogsie
No problem, mogsie, always interesting to discuss these types of things :-)I think I see where you guys are going with this, unfortunately I just don't understand enough about digest authentication to really grasp this (mostly I just don't understand how the token is sent back each HTTP request, but that seems to be an implementation detail). However, I do now see why this method does not violate REST principles. Thanks for the responses!
unforgiven3
You're welcome! wrt digest authentication tokens, there's a special field called "opaqe" which is designated to be echoed verbatim back.
mogsie