REST and authentication variants - authentication

I am currently working on a REST library for .net, and I would like to hear some opinions about an open point I have: REST and authentication.
Here is an example of an RESTful interface used with the library:
[RestRoot("/user")]
public interface IUserInterface
{
[RestPut("/")]
void Add(User user);
[RestGet("/")]
int[] List();
[RestGet("/get/{id}")]
User Get(int id);
[RestDelete("/delete/{id}")]
void Delete(int id);
}
The server code then just implements the interface and the clients can obtain the same interface through a factory. Or if the client is not using the library a standard HTTP request also works.
I know that there are the major ways of either using HTTP Basic Auth or sending a token to requests requiring authenticated users.
The first method (HTTP Basic Auth), has the following issues (partly web browser specific):
The password is transmitted with every request - even with SSL this has some kind of "bad feeling".
Since the password is transmitted with a request header, it would be easy for an local attacker to look at the transmitted headers to gain the password.
The password is available in the browsers memory.
No standard way to expire user "sessions".
Login with a browser interrupts the look and feel of a page.
The issues for the second method are more focused on implementation and library use:
Each request URI which needs authentication must have a parameter for the token, which is just very repetitive.
There is a lot more code to write if each method implementation needs to check if a token is valid.
The interface will become less specific e.g. [RestGet("/get/{id}")] vs. [RestGet("/get/{id}/{token}")].
Where to put the token: at the end of the URI? after the root? somewhere else?
My idea was to pass the token as parameter to the URL like http:/server/user/get/1234?token=token_id.
Another possibility would be to send the parameter as an HTTP header, but this would complicate usage with plain HTTP clients I guess.
The token would get passed back to the client as a custom HTTP header ("X-Session-Id") on each request.
This then could be completely abstracted from the interface, and any implementation needing authentication could just ask which user the token (if given) belongs to.
Do you think this would violate REST too much or do you have any better ideas?

I tend to believe that authentication details belong in the header, not the URI. If you rely on a token being placed on the URI, then every URI in your application will need to be encoded to include the token. It would also negatively impact caching. Resources with a token that is constantly changing will no longer be able to be cached. Resource related information belongs in the URI, not application related data such as credentials.
It seems you must be targeting web browsers as a client? If so you could investigate using HTTP Digest access authentication or issuing clients their own SSL certificates to uniquely identify and authenticate them. Also, I don't think that session cookies are necessarily a bad thing. Especially when having to deal with a browser. As long as you isolate the cookie handling code and make the rest of the application not rely on it you would be fine. The key is only store the user's identity in the session, nothing else. Do not abuse server side session state.
If you are targeting clients other than the browser then there are a number of approaches you can take. I've had luck with using Amazon's S3 Authentication mechanism.
This is all very subjective of course. Purity and following REST to the letter can sometimes be impractical. As long as you minimize and isolate such behavior, the core of your application can still be RESTful. I highly recommend RESTful Web Services as a great source of REST information and approaches.

I agree with workmad3, if session life time needs to be maintained you should create a session resource. Post on that resource with user credentials (either basic authentication or credentials in the body content) will return unique session id. Delete on /session/{id} will log out the user.
If you want to control the session expiry time. When creating new session (post on session resource) the server will set a cookie on the response (using standard set-cookie header).
The cookie will contain expiry time. The cookie string should be encrypted on the server, so only the server can open that cookie.
Every consequent request to the server will send the session cookie in the cookie header. (it will be done automatically for you if your client is a browser). The server needs to "renew" the cookie for every request, i.e. create new cookie with new expiry time (extend session's timeout).
Remember to clear the cookie when the user calls delete on the session resource.
If you want your application to be more secured you can store the client IP in the cookie itself, so when a request arrives the server can validate that it was sent from the "original" client. But remember that this solution can be problematic when proxies are involved, because the server might "see" all the requests as coming from the same client.

The rest authentication I've seen treats the sessions as a REST resource for creation, destruction etc. and then the session ID is passed to and fro. The ones I've seen tend to use the session cookie for this as it's the only way to secure it really. If you pass the session id in the URL, you don't have any way of really authenticating it came from the correct client.
Authentication is a tricky problem with REST though, as it requires some form of state to be kept outside the URL which infringes upon REST principles of the URL being all that is required to represent state.

Related

Vue protecting paths from edited localstorage [duplicate]

When building SPA style applications using frameworks like Angular, Ember, React, etc. what do people believe to be some best practices for authentication and session management? I can think of a couple of ways of considering approaching the problem.
Treat it no differently than authentication with a regular web application assuming the API and and UI have the same origin domain.
This would likely involve having a session cookie, server side session storage and probably some session API endpoint that the authenticated web UI can hit to get current user information to help with personalization or possibly even determining roles/abilities on the client side. The server would still enforce rules protecting access to data of course, the UI would just use this information to customize the experience.
Treat it like any third-party client using a public API and authenticate with some sort of token system similar to OAuth. This token mechanism would used by the client UI to authenticate each and every request made to the server API.
I'm not really much of an expert here but #1 seems to be completely sufficient for the vast majority of cases, but I'd really like to hear some more experienced opinions.
This question has been addressed, in a slightly different form, at length, here:
RESTful Authentication
But this addresses it from the server-side. Let's look at this from the client-side. Before we do that, though, there's an important prelude:
Javascript Crypto is Hopeless
Matasano's article on this is famous, but the lessons contained therein are pretty important:
https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/
To summarize:
A man-in-the-middle attack can trivially replace your crypto code with <script> function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script>
A man-in-the-middle attack is trivial against a page that serves any resource over a non-SSL connection.
Once you have SSL, you're using real crypto anyways.
And to add a corollary of my own:
A successful XSS attack can result in an attacker executing code on your client's browser, even if you're using SSL - so even if you've got every hatch battened down, your browser crypto can still fail if your attacker finds a way to execute any javascript code on someone else's browser.
This renders a lot of RESTful authentication schemes impossible or silly if you're intending to use a JavaScript client. Let's look!
HTTP Basic Auth
First and foremost, HTTP Basic Auth. The simplest of schemes: simply pass a name and password with every request.
This, of course, absolutely requires SSL, because you're passing a Base64 (reversibly) encoded name and password with every request. Anybody listening on the line could extract username and password trivially. Most of the "Basic Auth is insecure" arguments come from a place of "Basic Auth over HTTP" which is an awful idea.
The browser provides baked-in HTTP Basic Auth support, but it is ugly as sin and you probably shouldn't use it for your app. The alternative, though, is to stash username and password in JavaScript.
This is the most RESTful solution. The server requires no knowledge of state whatsoever and authenticates every individual interaction with the user. Some REST enthusiasts (mostly strawmen) insist that maintaining any sort of state is heresy and will froth at the mouth if you think of any other authentication method. There are theoretical benefits to this sort of standards-compliance - it's supported by Apache out of the box - you could store your objects as files in folders protected by .htaccess files if your heart desired!
The problem? You are caching on the client-side a username and password. This gives evil.ru a better crack at it - even the most basic of XSS vulnerabilities could result in the client beaming his username and password to an evil server. You could try to alleviate this risk by hashing and salting the password, but remember: JavaScript Crypto is Hopeless. You could alleviate this risk by leaving it up to the Browser's Basic Auth support, but.. ugly as sin, as mentioned earlier.
HTTP Digest Auth
Is Digest authentication possible with jQuery?
A more "secure" auth, this is a request/response hash challenge. Except JavaScript Crypto is Hopeless, so it only works over SSL and you still have to cache the username and password on the client side, making it more complicated than HTTP Basic Auth but no more secure.
Query Authentication with Additional Signature Parameters.
Another more "secure" auth, where you encrypt your parameters with nonce and timing data (to protect against repeat and timing attacks) and send the. One of the best examples of this is the OAuth 1.0 protocol, which is, as far as I know, a pretty stonking way to implement authentication on a REST server.
https://www.rfc-editor.org/rfc/rfc5849
Oh, but there aren't any OAuth 1.0 clients for JavaScript. Why?
JavaScript Crypto is Hopeless, remember. JavaScript can't participate in OAuth 1.0 without SSL, and you still have to store the client's username and password locally - which puts this in the same category as Digest Auth - it's more complicated than HTTP Basic Auth but it's no more secure.
Token
The user sends a username and password, and in exchange gets a token that can be used to authenticate requests.
This is marginally more secure than HTTP Basic Auth, because as soon as the username/password transaction is complete you can discard the sensitive data. It's also less RESTful, as tokens constitute "state" and make the server implementation more complicated.
SSL Still
The rub though, is that you still have to send that initial username and password to get a token. Sensitive information still touches your compromisable JavaScript.
To protect your user's credentials, you still need to keep attackers out of your JavaScript, and you still need to send a username and password over the wire. SSL Required.
Token Expiry
It's common to enforce token policies like "hey, when this token has been around too long, discard it and make the user authenticate again." or "I'm pretty sure that the only IP address allowed to use this token is XXX.XXX.XXX.XXX". Many of these policies are pretty good ideas.
Firesheeping
However, using a token Without SSL is still vulnerable to an attack called 'sidejacking': http://codebutler.github.io/firesheep/
The attacker doesn't get your user's credentials, but they can still pretend to be your user, which can be pretty bad.
tl;dr: Sending unencrypted tokens over the wire means that attackers can easily nab those tokens and pretend to be your user. FireSheep is a program that makes this very easy.
A Separate, More Secure Zone
The larger the application that you're running, the harder it is to absolutely ensure that they won't be able to inject some code that changes how you process sensitive data. Do you absolutely trust your CDN? Your advertisers? Your own code base?
Common for credit card details and less common for username and password - some implementers keep 'sensitive data entry' on a separate page from the rest of their application, a page that can be tightly controlled and locked down as best as possible, preferably one that is difficult to phish users with.
Cookie (just means Token)
It is possible (and common) to put the authentication token in a cookie. This doesn't change any of the properties of auth with the token, it's more of a convenience thing. All of the previous arguments still apply.
Session (still just means Token)
Session Auth is just Token authentication, but with a few differences that make it seem like a slightly different thing:
Users start with an unauthenticated token.
The backend maintains a 'state' object that is tied to a user's token.
The token is provided in a cookie.
The application environment abstracts the details away from you.
Aside from that, though, it's no different from Token Auth, really.
This wanders even further from a RESTful implementation - with state objects you're going further and further down the path of plain ol' RPC on a stateful server.
OAuth 2.0
OAuth 2.0 looks at the problem of "How does Software A give Software B access to User X's data without Software B having access to User X's login credentials."
The implementation is very much just a standard way for a user to get a token, and then for a third party service to go "yep, this user and this token match, and you can get some of their data from us now."
Fundamentally, though, OAuth 2.0 is just a token protocol. It exhibits the same properties as other token protocols - you still need SSL to protect those tokens - it just changes up how those tokens are generated.
There are two ways that OAuth 2.0 can help you:
Providing Authentication/Information to Others
Getting Authentication/Information from Others
But when it comes down to it, you're just... using tokens.
Back to your question
So, the question that you're asking is "should I store my token in a cookie and have my environment's automatic session management take care of the details, or should I store my token in Javascript and handle those details myself?"
And the answer is: do whatever makes you happy.
The thing about automatic session management, though, is that there's a lot of magic happening behind the scenes for you. Often it's nicer to be in control of those details yourself.
I am 21 so SSL is yes
The other answer is: Use https for everything or brigands will steal your users' passwords and tokens.
You can increase security in authentication process by using JWT (JSON Web Tokens) and SSL/HTTPS.
The Basic Auth / Session ID can be stolen via:
MITM attack (Man-In-The-Middle) - without SSL/HTTPS
An intruder gaining access to a user's computer
XSS
By using JWT you're encrypting the user's authentication details and storing in the client, and sending it along with every request to the API, where the server/API validates the token. It can't be decrypted/read without the private key (which the server/API stores secretly) Read update.
The new (more secure) flow would be:
Login
User logs in and sends login credentials to API (over SSL/HTTPS)
API receives login credentials
If valid:
Register a new session in the database Read update
Encrypt User ID, Session ID, IP address, timestamp, etc. in a JWT with a private key.
API sends the JWT token back to the client (over SSL/HTTPS)
Client receives the JWT token and stores in localStorage/cookie
Every request to API
User sends a HTTP request to API (over SSL/HTTPS) with the stored JWT token in the HTTP header
API reads HTTP header and decrypts JWT token with its private key
API validates the JWT token, matches the IP address from the HTTP request with the one in the JWT token and checks if session has expired
If valid:
Return response with requested content
If invalid:
Throw exception (403 / 401)
Flag intrusion in the system
Send a warning email to the user.
Updated 30.07.15:
JWT payload/claims can actually be read without the private key (secret) and it's not secure to store it in localStorage. I'm sorry about these false statements. However they seem to be working on a JWE standard (JSON Web Encryption).
I implemented this by storing claims (userID, exp) in a JWT, signed it with a private key (secret) the API/backend only knows about and stored it as a secure HttpOnly cookie on the client. That way it cannot be read via XSS and cannot be manipulated, otherwise the JWT fails signature verification. Also by using a secure HttpOnly cookie, you're making sure that the cookie is sent only via HTTP requests (not accessible to script) and only sent via secure connection (HTTPS).
Updated 17.07.16:
JWTs are by nature stateless. That means they invalidate/expire themselves. By adding the SessionID in the token's claims you're making it stateful, because its validity doesn't now only depend on signature verification and expiry date, it also depends on the session state on the server. However the upside is you can invalidate tokens/sessions easily, which you couldn't before with stateless JWTs.
I would go for the second, the token system.
Did you know about ember-auth or ember-simple-auth? They both use the token based system, like ember-simple-auth states:
A lightweight and unobtrusive library for implementing token based
authentication in Ember.js applications.
http://ember-simple-auth.simplabs.com
They have session management, and are easy to plug into existing projects too.
There is also an Ember App Kit example version of ember-simple-auth: Working example of ember-app-kit using ember-simple-auth for OAuth2 authentication.

Api Token Authentication - through parameters or headers?

I wrote some API. It requires an API token.
I only access this API through backend.
Should I receive the API token through headers only, or is it ok to receive it from query string parameters?
Are there differences security-wise?
Edit: forgot to mention, of course I use SSL
All the Authorization is in Headers only headers are more secure
In query parameter these are expose for the public
for eg. if you send in Like a query it will be public to all
Don't do this Ever
curl -X GET http://localhost:5051/v1/user/verifytoken?token=bearer-xdrRxfdfdfdf
You may need a refresher on the differences between cookies and tokens to assist you in finding your answer.
The purpose of cookies is to bring state to what is inherently a stateless protocol which is http, the http protocol has no concept of state and it's only by introducing these cookies or tiny bits of data on requests that identify us to the server.
Cookies are included on all http requests by default, they manifest themselves as a property on the header of any request. A server can choose to place information on a users cookie that identifies them uniquely to that particular server.
So if they were logging into a website I were making I could stick some information into that cookie that says this is user13794 and on any follow up request they would have a cookie 13794 that says this is the same user coming back, it's another request from the same person.
Cookies are automatically included on all requests and very importantly, are unique to each domain, such as Google.com versus eBay.com. A cookie you have that is tied to google.com is not and cannot be shared by default with ebay.com, that is how we get some level of security on all of our requests. So if I logged on to google.com and then went to hacker.com, the hacker.com website could not lift my cookie from Google and hijack my session.
SO cookies cannot be sent to different domains, that is something that exists for security purposes so you cannot easily hijack peoples sessions.
Opposed to cookies are the ideas of tokens, this was introduced as a convention, to use tokens in place of cookies where cookies stop being useful.
There is nothing done automatically for us with tokens, we have to manually include a header with our token which might be a string of letters and numbers and we might include it on a specific header so we have to manually wire up our tokens at all times.
The benefits of tokens is that we can send them to any domain that we wish, so if I am on google.com and I want to make an authenticated request to an entirely different domain, I can do so by using a token.
I would make my request to that other domain, include my particular token and boom! I am authenticated on that other domain.
So that's my long winded way of saying, like with cookies, tokens are manually wired up through headers only, not query parameters.

CouchDB Proxy Authentication security - user roles confusion

On user auth success my auth server generates a token and passes it to the client.
The docs say that the client has to add the following headers:
X-Auth-CouchDB-UserName: username;
X-Auth-CouchDB-Roles:comma-separated (,) list of user roles;
X-Auth-CouchDB-Token: authentication token.
Does it mean that the client defines his own roles on every request? Why can't he add 'admin' into the list of roles then?
A client is anything that uses or requests resources from a server.
"The client" in this case is your proxy/auth server, not a web browser. (The documentation could probably stand to be clarified a bit.)
So yes, your proxy/auth server, the client to CouchDB, should set that header as appropriate.
By extension, it should also not pass through any X-Auth-Couch headers received from its client (presumably a web browser).
Good observation. Using the JWT Authentication would seem to close this loophole as my understanding is the entire token is signed-over.
That said, in neither case can one avoid:
having to fully trust the entity holding the secret
having to carefully guard against leakage of its headers
The former is sort of unavoidable, as the point of these plugins is to delegate authentication. Either you trust the proxy (or JWT issuer) or you leave those authentication_handlers disabled.
The latter is something that e.g. OAuth 1 hardened itself somewhat against, in that ± the entire request was signed over and one couldn't simply take a couple auth headers from an earlier leaked request and slap them on a new forged request. Nonce and timestamp fields were supposed to be checked to avoid verbatim replays of prior requests as well. (All this was dropped in OAuth 2 for whatever that's worth… and even OAuth 1 had some notable loopholes in practice…)
So in practice either the Proxy or the JWT authentication handlers should be used with care. Assuming a "firewall" of sorts drawn around both your CouchDB and authentication source, then as #Flimzy's answer mentions preventing unexpected headers making their way inwards from outside that boundary — as well as keeping the real headers from leaking outwards — should mitigate most potential abuse.

Authentication, Authorization and Session Management in Traditional Web Apps and APIs

Correct me if I am wrong: In a traditional web application, the browser automatically appends session information into a request to the server, so the server can know who the request comes from. What exactly is appended actually?
However, in a API based app, this information is not sent automatically, so when developing an API, I must check myself if the request comes from an authenticated user for example? How is this normally done?
HTTP Protocol is stateless by design, each request is done separately and is executed in a separate context.
The idea behind session management is to put requests from the same client in the same context. This is done by issuing an identifier by the server and sending it to the client, then the client would save this identifier and resend it in subsequent requests so the server can identify it.
Cookies
In a typical browser-server case; the browser manages a list of key/value pairs, known as cookies, for each domain:
Cookies can be managed by the server (created/modified/deleted) using the Set-Cookie HTTP response header.
Cookies can be accessed by the server (read) by parsing the Cookie HTTP request header.
Web-targeted programming languages/frameworks provide functions to deal with cookies on a higher level, for example, PHP provides setcookie/$_COOKIE to write/read cookies.
Sessions
Back to sessions, In a typical browser-server case (again), server-side session management takes advantage of client-side cookie management. PHP's session management sets a session id cookie and use it to identify subsequent requests.
Web applications API?
Now back to your question; since you'd be the one responsible for designing the API and documenting it, the implementation would be your decision. You basically have to
give the client an identifier, be it via a Set-Cookie HTTP response header, inside the response body (XML/JSON auth response).
have a mechanism to maintain identifier/client association. for example a database table that associates identifier 00112233445566778899aabbccddeeff with client/user #1337.
have the client resend the identifier sent to it at (1.) in all subsequent requests, be it in an HTTP Cookie request header, a ?sid=00112233445566778899aabbccddeeff param(*).
lookup the received identifier, using the mechanism at (2.), check if a valid authentication, and is authorized to do requested operation, and then proceed with the operation on behalf on the auth'd user.
Of course you can build upon existing infrastructure, you can use PHP's session management (that would take care of 1./2. and the authentication part of 4.) in your app, and require that client-side implementation do cookie management(that would take care of 3.), and then you do the rest of your app logic upon that.
(*) Each approach has cons and pros, for example, using a GET request param is easier to implement, but may have security implications, since GET requests are logged. You should use https for critical (all?) applications.
The session management is server responsibility. When session is created, a session token is generated and sent to the client (and stored in a cookie). After that, in the next requests between client and server, the client sends the token (usually) as an HTTP cookie. All session data is stored on the server, the client only stores the token. For example, to start a session in PHP you just need to:
session_start(); // Will create a cookie named PHPSESSID with the session token
After the session is created you can save data on it. For example, if you want to keep a user logged:
// If username and password match, you can just save the user id on the session
$_SESSION['userID'] = 123;
Now you are able to check whether a user is authenticated or not:
if ($_SESSION['userID'])
echo 'user is authenticated';
else
echo 'user isn't authenticated';
If you want, you can create a session only for an authenticated user:
if (verifyAccountInformation($user,$pass)){ // Check user credentials
// Will create a cookie named PHPSESSID with the session token
session_start();
$_SESSION['userID'] = 123;
}
There are numerous way for authentic users, both for Web applications and APIs. There are couple of standards, or you can write your own custom authorization / and or authentication. I would like to point out difference between authorization and authentication. First, application needs to authenticate user(or api client) that request is coming from. Once user has been authenticated, based on user's identity application needs to determine whatever authenticated user has permission to perform certain application (authorization). For the most of traditional web applications, there is no fine granularity in security model, so once the user is authenticated, it's in most cases also and authorized to perform certain action. However, this two concepts (authentication and authorization) should be as two different logical operations.
Further more, in classical web applications, after user has been authenticated and authorized
(mostly by looking up username/password pair in database), authorization and identity info is written in session storage. Session storage does not have to be server side, as most of the answers above suggest, it could also be stored in cookie on client side, encrypted in most cases. For an example, PHP CodeIgniter framework does this by default. There is number of mechanism for protecting session on client side, and I don't see this way of storing session data any less secure than storing sessionId, which is then looked up in session storage on server-side. Also, storing session client-side is quite convenient in distributed environment, because it eliminates need for designing solution (or using already existing one) for central session management on server side.
Further more, authenticating with simple user-password pair does not have to be in all case done trough custom code which looks up matching user-record in database. There is, for example basic authentication protocol , or digest authentication. On proprietary software like Windows platform, there are also ways of authenticating user trough, for an example,ActiveDirectory
Providing username/password pair is not only way to authenticate, if using HTTPS protocol, you can also consider authentication using digital certificates.
In specific use case, if designing web service, which uses SOAP as protocol, there is also WS-Security extension for SOAP protocol.
With all these said, I would say that answers to following question enter decision procedure for choice of authorization/authentication mechanism for WebApi:
1) What's the targeted audience, is it publicly available, or for registered(paying) members only?
2) Is it run or *NIX, or MS platform
3) What number of users is expected
4) How much sensitive data API deals with (stronger vs weaker authentication mechanisms)
5) Is there any SSO service that you could use
.. and many more.
Hope that this clears things bit, as there are many variables in equation.
If the API based APP is a Client, then the API must have option to retrieve/read the cookies from server response stream and store it. For automatic appending of cookies while preparing request object for same server/url. If it is not available, session id cannot be retrieved.
You are right, well the reason things are 'automatic' in a standard environment is because cookies are preferred over URL propagation to keep things pretty for the users. That said, the browser (client software) manages storing and sending the session cookie along with every request.
In the API world, simple systems often just have authentication credentials passed along with every request (at least in my line of work). Client authors are typically (again in my experience) reluctant to implement cookie storage, and transmission with every request and generally anything more than the bare minimum...
There are plenty of other authentication mechanisms out there for HTTP-based APIs, HTTP basic / digest to name a couple, and of course the ubiquitous o-auth which is designed specifically for these things if I'm not mistaken. No cookies are maintained, credentials are part of every exchange (fairly sure on that).
The other thing to consider is what you're going to do w/ the session on the server in an API. The session on a website provides storage for the current user, and typically stores small amounts of data to take load off the db from page to page. In an API context this is less of a need as things are more-or-less stateless, speaking generally of course; it really depends what the service is doing.
I would suggest you send some kind of token with each request.
Dependent on the server and service those can be a JSESSIONID parameter in your GET/POST request or something mature like SAML in SOAP over HTTP in your Web Service request.

REST GET requests, verbs and apikey

I want to create a flexible API Rest server. I will allow the clients to authenticate using HTTP or an APIKEY.
My question is: what is the correct way to add the apikey to a GET request? My problem is the apikey pollutes the url.
I imagine something like this : /book/1/apikey/s4cr4t !
In my opinion you should only use the Authorization header. That's what it is there for.
Putting it in the URL is a bad idea because:
a) as you said it pollutes the URL
b) if you decide to go SSL for security then the API will still appear in log files
c) caches will end up creating multiple copies of the same representation, one for each api key.
For more information on creating your own Authorization scheme go here.
Credentials may be passed using the Authorization header:
GET http://domain.com:/book/1
Authorization: apikey="s4cr4t"
It all depends on how far you want to go but the mechanics stays the same:
Context
The goal is to identify the client with some level of security. (Note: Security is another detailed discussion). Remember that one if the “features” of REST is to be stateless: That means no session state on the server except for resources. To keep the client stateless, it needs to supply on each request enough information that the request is independent. It must give the server a way to identify the client such as a username/password, API Key or token.
You have various options to do this so here are some:
Add HTTP headers to identify the client
Here one can use the Authorization header and send it with each request. There are various authentication schemes but stick to the standard ones such as Basic Auth. Here you would probably stick to SSL. The authentication process generates a kind of token if you like.
You can also make use of a cookie. The cookie must contain no information except that it is a “pointer or key” to a stateful session resource on your server (note: session it a resource which is “rest-legal”). You can create this resource by doing a PUT (+info) with response 200 OK or POST (+info) with a response of 201 Created and Location: /sessions/123334. The session can then be validated by the server such as timeout, valid client ip address, api key etc.
With the method above, you can also define a customer header such as Api-Key: XXXX. But then you limit yourself to special client. Set-Cookie are “well known” headers so browser will handle them kind of transparently. The authentication process can then be done by following links and filling in forms (PUT + POST) to authenticate (create session resource).
Encode an identifier in the content
Here you are free to do what you want too. Just add a field/token/id to your content and let the server verify it.
A RESTful API does application flow by resolving links. See also HATEOAS and Fielding's words. This also applies when you have a separate process of logging in to the application.
Do not encode any data in the URIs. (Out of band information)