What is the difference between token authentication and authentication using cookies?
I am trying to implement the Ember Auth Rails Demo but I do not understand the reasons behind using token authentication as described in the Ember Auth FAQ on the question "Why token authentication?"
HTTP is stateless. In order to authorize you, you have to "sign" every single request you're sending to server.
Token authentication
A request to the server is signed by a "token" - usually it means setting specific HTTP headers, however, they can be sent in any part of the HTTP request (POST body, etc.)
Pros:
You can authorize only the requests you wish to authorize. (Cookies - even the authorization cookie are sent for every single request.)
Immune to XSRF (Short example of XSRF - I'll send you a link in email that will look like , and if you're logged in via cookie authentication to bank.example, and bank.example doesn't have any means of XSRF protection, I'll withdraw money from your account simply by the fact that your browser will trigger an authorized GET request to that url.) Note there are anti forgery measure you can do with cookie-based authentication - but you have to implement those.
Cookies are bound to a single domain. A cookie created on the domain foo.example can't be read by the domain bar.example, while you can send tokens to any domain you like. This is especially useful for single page applications that are consuming multiple services that are requiring authorization - so I can have a web app on the domain myapp.example that can make authorized client-side requests to myservice1.example and to myservice2.example.
Cons: You have to store the token somewhere; while cookies are stored "out of the box". The locations that comes to mind are localStorage (con: the token is persisted even after you close browser window), sessionStorage (pro: the token is discarded after you close browser window, con: opening a link in a new tab will render that tab anonymous) and cookies (Pro: the token is discarded after you close the browser window. If you use a session cookie you will be authenticated when opening a link in a new tab, and you're immune to XSRF since you're ignoring the cookie for authentication, you're just using it as token storage. Con: cookies are sent out for every single request. If this cookie is not marked as https only, you're open to man in the middle attacks.)
You have to store the token somewhere; while cookies are stored "out of the box". The locations that comes to mind are localStorage (con: the token is persisted even after you close browser window), sessionStorage (pro: the token is discarded after you close browser window, con: opening a link in a new tab will render that tab anonymous) and cookies (Pro: the token is discarded after you close the browser window. If you use a session cookie you will be authenticated when opening a link in a new tab, and you're immune to XSRF since you're ignoring the cookie for authentication, you're just using it as token storage. Con: cookies are sent out for every single request. If this cookie is not marked as https only, you're open to man in the middle attacks.)
It is slightly easier to do XSS attack against token based authentication (i.e. if I'm able to run an injected script on your site, I can steal your token; however, cookie based authentication is not a silver bullet either - while cookies marked as http-only can't be read by the client, the client can still make requests on your behalf that will automatically include the authorization cookie.)
Requests to download a file, which is supposed to work only for authorized users, requires you to use File API. The same request works out of the box for cookie-based authentication.
Cookie authentication
A request to the server is always signed in by authorization cookie.
Pros: Cookies can be marked as "http-only" which makes them impossible to be read on the client side. This is better for XSS-attack protection. Comes out of the box - you don't have to implement any code on the client side.
Cookies can be marked as "http-only" which makes them impossible to be read on the client side. This is better for XSS-attack protection.
Comes out of the box - you don't have to implement any code on the client side.
Cons: Bound to a single domain. (So if you have a single page application that makes requests to multiple services, you can end up doing crazy stuff like a reverse proxy.) Vulnerable to XSRF. You have to implement extra measures to make your site protected against cross site request forgery. Are sent out for every single request, (even for requests that don't require authentication).
Bound to a single domain. (So if you have a single page application that makes requests to multiple services, you can end up doing crazy stuff like a reverse proxy.)
Vulnerable to XSRF. You have to implement extra measures to make your site protected against cross site request forgery.
Are sent out for every single request, (even for requests that don't require authentication).
Overall, I'd say tokens give you better flexibility, (since you're not bound to single domain). The downside is you have to do quite some coding by yourself.
For Googlers:
DO NOT mix statefulness with state transfer mechanisms
STATEFULNESS
Stateful = save authorization info on server side, this is the traditional way
Stateless = save authorization info on client side, along with a signature to ensure integrity
MECHANISMS
Cookie = a special header with special treatment (access, storage, expiration, security, auto-transfer) by browsers
Custom Headers = e.g. Authorization, are just headers without any special treatment, client has to manage all aspects of the transfer
Other. Other transfer mechanisms may be utilized, e.g. query string was a choice to transfer auth ID for a while but was abandoned for its insecurity
STATEFULNESS COMPARISON
"Stateful authorization" means the server stores and maintains user authorization info on server, making authorizations part of the application state
This means client only need to keep an "auth ID" and the server can read auth detail from its database
This implies that server keeps a pool of active auths (users that are logged in) and will query this info for every request
"Stateless authorization" means the server does not store and maintain user auth info, it simply does not know which users are signed in, and rely on the client to produce auth info
Client will store complete auth info like who you are (user ID), and possibly permissions, expiration time, etc., this is more than just auth ID, so it is given a new name token
Obviously client cannot be trusted, so auth data is stored along with a signature generated from hash(data + secret key), where secret key is only known to server, so the integrity of token data can be verified
Note that token mechanism merely ensures integrity, but not confidentiality, client has to implement that
This also means for every request client has to submit a complete token, which incurs extra bandwidth
MECHANISM COMPARISON
"Cookie" is just a header, but with some preloaded operations on browsers
Cookie can be set by server and auto-saved by client, and will auto-send for same domain
Cookie can be marked as httpOnly thus prevent client JavaScript access
Preloaded operations may not be available on platforms other than browsers (e.g. mobile), which may lead to extra efforts
"Custom headers" are just custom headers without preloaded operations
Client is responsible to receive, store, secure, submit and update the custom header section for each requests, this may help prevent some simple malicious URL embedding
SUM-UP
There is no magic, auth state has to be stored somewhere, either at server or client
You may implement stateful/stateless with either cookie or other custom headers
When people talk about those things their default mindset is mostly: stateless = token + custom header, stateful = auth ID + cookie; these are NOT the only possible options
They have pros and cons, but even for encrypted tokens you should not store sensitive info
A typical web app is mostly stateless, because of its request/response nature. The HTTP protocol is the best example of a stateless protocol. But since most web apps need state, in order to hold the state between server and client, cookies are used such that the server can send a cookie in every response back to the client. This means the next request made from the client will include this cookie and will thus be recognized by the server. This way the server can maintain a session with the stateless client, knowing mostly everything about the app's state, but stored in the server. In this scenario at no moment does the client hold state, which is not how Ember.js works.
In Ember.js things are different. Ember.js makes the programmer's job easier because it holds indeed the state for you, in the client, knowing at every moment about its state without having to make a request to the server asking for state data.
However, holding state in the client can also sometimes introduce concurrency issues that are simply not present in stateless situations. Ember.js, however, deals also with these issues for you; specifically ember-data is built with this in mind. In conclusion, Ember.js is a framework designed for stateful clients.
Ember.js does not work like a typical stateless web app where the session, the state and the corresponding cookies are handled almost completely by the server. Ember.js holds its state completely in Javascript (in the client's memory, and not in the DOM like some other frameworks) and does not need the server to manage the session. This results in Ember.js being more versatile in many situations, e.g. when your app is in offline mode.
Obviously, for security reasons, it does need some kind of token or unique key to be sent to the server everytime a request is made in order to be authenticated. This way the server can look up the send token (which was initially issued by the server) and verify if it's valid before sending a response back to the client.
In my opinion, the main reason why to use an authentication token instead of cookies as stated in Ember Auth FAQ is primarily because of the nature of the Ember.js framework and also because it fits more with the stateful web app paradigm. Therefore the cookie mechanism is not the best approach when building an Ember.js app.
I hope my answer will give more meaning to your question.
Tokens need to be stored somewhere (local/session storage or cookies)
Tokens can expire like cookies, but you have more control
Local/session storage won't work across domains, use a marker cookie
Preflight requests will be sent on each CORS request
When you need to stream something, use the token to get a signed request
It's easier to deal with XSS than XSRF
The token gets sent on every request, watch out its size
If you store confidential info, encrypt the token
JSON Web Tokens can be used in OAuth
Tokens are not silver bullets, think about your authorization use cases carefully
http://blog.auth0.com/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies/
http://blog.auth0.com/2014/01/07/angularjs-authentication-with-cookies-vs-token/
I believe that there is some confusion here. The significant difference between cookie based authentication and what is now possible with HTML5 Web Storage is that browsers are built to send cookie data whenever they are requesting resources from the domain that set them. You can't prevent that without turning off cookies. Browsers do not send data from Web Storage unless code in the page sends it. And pages can only access data that they stored, not data stored by other pages.
So, a user worried about the way that their cookie data might be used by Google or Facebook might turn off cookies. But, they have less reason to turn off Web Storage (until the advertisers figure a way to use that as well).
So, that's the difference between cookie based and token based, the latter uses Web Storage.
Token based authentication is stateless, server need not store user information in the session. This gives ability to scale application without worrying where the user has logged in. There is web Server Framework affinity for cookie based while that is not an issue with token based. So the same token can be used for fetching a secure resource from a domain other than the one we are logged in which avoids another uid/pwd authentication.
Very good article here:
Use Token when...
Federation is desired. For example, you want to use one provider (Token Dispensor) as the token issuer, and then use your api server as the token validator. An app can authenticate to Token Dispensor, receive a token, and then present that token to your api server to be verified. (Same works with Google Sign-In. Or Paypal. Or Salesforce.com. etc)
Asynchrony is required. For example, you want the client to send in a request, and then store that request somewhere, to be acted on by a separate system "later". That separate system will not have a synchronous connection to the client, and it may not have a direct connection to a central token dispensary. a JWT can be read by the asynchronous processing system to determine whether the work item can and should be fulfilled at that later time. This is, in a way, related to the Federation idea above. Be careful here, though: JWT expire. If the queue holding the work item does not get processed within the lifetime of the JWT, then the claims should no longer be trusted.
Cient Signed request is required. Here, request is signed by client using his private key and server would validate using already registered public key of the client.
One of the primary differences is that cookies are subject to Same Origin Policy whereas tokens are not. This creates all kinds of down stream effects.
Since cookies are only sent to and from a particular host that host must bear the burden of authenticating the user and the user must create an account with security data with that host in order to be verifiable.
Tokens on the other hand are issued and are not subject to same origin policy. The issuer can be literally anybody and it is up to the host to decide which issuers to trust. An issuer like Google and Facebook is typically well trusted so a host can shift the burden of authenticating the user (including storing all user security data) to another party and the user can consolidate their personal data under a specific issuer and not have to remember a bunch of different passwords for each host they interact with.
This allows for single sign on scenarios that reduce overall friction in the user experience. In theory the web also becomes more secure as specialised identity providers emerge to provide auth services instead of having every ma and pa website spinning up their own, likely half baked, auth systems. And as these providers emerge the cost of providing secure web resources for even very basic resources trends towards zero.
So in general tokens reduce the friction and costs associated with providing authentication and shifts the burden of the various aspects of a secure web to centralised parties better able to both implement and maintain security systems.
In short:
JWT vs Cookie Auth
| | Cookie | JWT |
| Stateless | No | Yes |
| Cross domain usage | No | Yes |
| Mobile ready | No | Yes |
| Performance | Low | High (no need in request to DB) |
| Add to request | Automatically | Manually (if not in cookie) |
Success story sharing
Are send out for every single request
Tokens are send for every request toocrazy stuff like a reverse proxy.
Overall, great answer, but I feel this part is somewhat misleading. Reverse proxying an API underneath a single URL endpoint is not crazy, and sometimes required (had to once for a SPA website to support IE9 clients). Having a separate endpoint for your API is great for spreading load, especially in a SPA website, or scenario where your API is heavily used by other applications. Labeling reverse proxy as "crazy stuff" is a tad much.