I am building an Authorization Server in terms of OAuth 2.0.
There is also a 3rd party web application (Client) which is using my Authorization Server. It's a regular web application, and the user may have several active sessions established with this application (for example, office and home machine, or just several web browsers on the same machine).
My Authorization Server issues an access token #1 (with or without the refresh token, that's not so important here) for Client once. When the user starts a new session with the Client, should the Authorization Server give the Client app the same access token #1 for that new session or should it issue a new #2 token?
My thougts:
From security point of view the new token might sound better, but then if the user wants to manage his authorizations, he will see a separate entry for each Client session, which might be messy.
For example, GitHub returns the same token for previously authorized clients, and on the "applications" page in my GitHub account I see only one entry per application, no matter how many sessions I've started, which is convenient.
However, this approach means that I have to store access tokens in Authorization or Resource server in the reversible way (plain-text or encrypted with some known key) instead of using irreversible hashing (like you usually do with passwords, storing salt and password hash from bcrypt, pbkdf2 or something similar).
Please be advised that I am not a security expert and this explanation
is my general idea of oauth. Reason why I mentioned this in the
beginning is because I see you are CREATING YOUR OWN AUTH SERVER based
on oauth 2.0 protocol, which means down the road some people might be
using your server for authentication, and thus I don't want you to
have the wrong concept.
The session-oauth mismatch
I want to clear this first that don't mix sessions and oauth. These are two separate things usually found working together IMHO.
Oauth protocol simply gives the apps/users with an access token via which the app/user can query your server for data associated with the token.
Session on the other hand depends on the application itself. Once some app received the token, they make a session out of it. When user logs in or logs out, the session is destroyed, not the oauth.
So what is the fate of oauth token?
Well from a server standpoint, each of your token should expire after a certain time period. That is it. Server does not know anything else. It gives you the token, then expires it after 'n' seconds.
However, the app may decide that it wants to revoke the access token. Maybe their website was hacked, or maybe they are done with all api calls. Then they can send a special request to your server telling you to force-expire the token.
So what should I do about user opening multiple sessions?
ABSOLUTELY NOTHING. As an oauth service provider, you are not concerned with sessions at all. All you know is that if the app asks you for a token, you give them one.
However, I will answer you question about sessions as well. Should you spawn different sessions for the same user? I would say yes. If you have same session, then if you log out from one machine, and refresh the page in second machine, since the session has expired, your other browser/machines will also log out naturally.
So how does github manages to not show extra entries?
Well I do not work for them so I don't know. But I guess that they will check each session, and if two or more sessions are associate with the same user, they know the user must be using many devices. Then when one of your devices sends some request to github, they can guess from the IP address your location, and if many of your machines are making requests from same place, you got to be using multiple machines. If not, then maybe some attacker is using your account as well.
This is how AFAIK banks predict malicious users - well not the only way, they sometimes also predict the pattern you are using to access bank records, and if that pattern is different, there are good chances that your account was compromised.
So now you may ask me, are you really sure that I should create as many tokens as the app demands me?
This is the part where I am not so sure. From what I have seen, oauth has two things. Google these two terms for more info:
Refresh Token: This token is not your access token. This token never expires, and once your access token is expired, you can use this token to get a new access token. This token is also to be kept secret.
Offline access type: Many oauth providers such as google and facebook also support this mode. This mode basically allows you to extend the expiry time of your access token. E.g. instead of normal expiry time of access token (e.g. 1 hour), for offline tokens you might have the expiry time of 1 year or so.
Answer to the question "Should I reuse OAuth 2.0 access tokens?"
Yes, the token is supposed to be used as many times as you need within the given expiry time (google sets it to 1 hour).
After it has expired, use the refresh token to get another access token and use it as many times as you need. Keep repeating the process.
If your users won't be online for you to start the oauth process, and you don't have the refresh token, then the app needs to have "offline" tokens.
Should I store my auth tokens?
You can if your app demands it, but it is nowhere recommended because of the potential to be leaked. Tokens are supposed to extract data within the given time limit and reissue the token when needed again. However, you surely can store them if you want.
"Offline" tokens, on the other hand, are expected to be stored. You can encrypt them if you like, but if the scopes are not too broad, I wouldn't bother at all.
Related
I've implemented lots of Restful APIs and web applications, I used to generate a JWT and give some time for expiration.
Currently I am developing mobile apps, and they all work on the same Restful APIs, but I am a bit confused of should the token expires in mobile apps and log out the user?
On many places, websites and as I do know JWT should never ever live eternally and the time for expiration must be kinda short period of time, maybe one day or less.
But if the mobile logs out the user, would it be considered bad User Experience
On the other hand, the user might click Remember me check box, so how would the JWT get expired?
Any idea would be appreciated.
There are several different ways to handle JWT expiration. First thing is to determine the value of your token. If you're using the token as a log-in to a game server, you might not be as worried about having a week-long expiration as you would for a banking app.
There are lots of ways to handle token expiration, but the most common I find below.
Automatic time-based expiration. This is a best practice, because a hijacked JWT will have less value. As you mention, logging the user out unexpectedly can be a poor experience, so one option are to include a "refresh" token, that can be exchanged once for a new, fresh, valid JWT token when the shorter-lived token expires. Refresh tokens have a longer lifetime, and may be bound to additional details such as a secure element on the device, or a policy such as in-session only (e.g. must obtain a new refresh token on app restart).
Policy-based revocation - instead of relying on a baked-in timeout, you can issue a revocation of the JWT. This relies on your services deciding when to revoke a login, and publishing the revocation somewhere it can be checked. This basically is what opaque tokens do, and thus you've just thrown away one of the advantages of JWT, but you can time out a session based on activity observed by your services.
Generally, these token management policies operate independently from the "remember me" function, which is usually a special "long-lived" (e.g. forever, 30 days, 90 days etc) token that is secured behind a secure element (e.g. fingerprint recognition, password etc) on the device that's used to obtain session tokens when a user starts a new app session.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
(spawned from this thread since this is really a question of its own and not specific to NodeJS etc)
I'm implementing a REST API server with authentication, and I have successfully implemented JWT token handling so that a user can login through a /login endpoint with username/password, upon which a JWT token is generated from a server secret and returned to the client. The token is then passed from the client to the server in each authenticated API request, upon which the server secret is used to verify the token.
However, I am trying to understand the best practices for exactly how and to what extent the token should be validated, to make a truly secure system. Exactly what should be involved in "validating" the token? Is it enough that the signature can be verified using the server-secret, or should I also cross-check the token and/or token payload against some data stored in the server?
A token based authentication system will only be as safe as passing username/password in each request provided that it's equally or more difficult to obtain a token than to obtain a user's password. However, in the examples I've seen, the only information required to produce a token is the username and the server-side secret. Doesn't this mean that assuming for a minute that a malicious user gains knowledge of the server secret, he can now produce tokens on behalf of any user, thereby having access not only to one given user as would be the fact if a password was obtained, but in fact to all user accounts?
This brings me to the questions:
1) Should JWT token validation be limited to verifying the signature of the token itself, relying on the integrity of the server secret alone, or accompanied by a separate validation mechanism?
In some cases I've seen the combined use of tokens and server sessions where upon successful login through the /login endpoint a session is established. API requests validate the token, and also compare the decoded data found in the token with some data stored in the session. However, using sessions means using cookies, and in some sense it defeats the purpose of using a token based approach. It also may cause problems for certain clients.
One could imagine the server keeping all tokens currently in use in a memcache or similar, to ensure that even if the server secret is compromised so that an attacker may produce "valid" tokens, only the exact tokens that were generated through the /login endpoint would be accepted. Is this reasonable or just redundant/overkill?
2) If JWT signature verification is the only means of validating tokens, meaning the integrity of the server secret is the breaking point, how should server secrets be managed? Read from an environment variable and created (randomized?) once per deployed stack? Re-newed or rotated periodically (and if so, how to handle existing valid tokens that were created before rotation but needs to be validated after rotation, perhaps it's enough if the server holds on to the current and the previous secret at any given time)? Something else?
Maybe I'm simply being overly paranoid when it comes to the risk of the server secret being compromised, which is of course a more general problem that needs to be addressed in all cryptographic situations...
I've been playing with tokens for my application as well. While I'm not an expert by any means, I can share some of my experiences and thoughts on the matter.
The point of JWTs is essentially integrity. It provides a mechanism for your server verify that the token that was provided to it is genuine and was supplied by your server. The signature generated via your secret is what provides for this. So, yes, if your secret is leaked somehow, that individual can generate tokens that your server would think are its own. A token based system would still be more secure than your username/password system simply because of the signature verification. And in this case, if someone has your secret anyway, your system has other security issues to deal with than someone making fake tokens (and even then, just changing the secret ensures that any tokens made with the old secret are now invalid).
As for payload, the signature will only tell you that the token provided to you was exactly as it was when your server sent it out. verifying the that the payloads contents are valid or appropriate for your application is obviously up to you.
For your questions:
1.) In my limited experience, it's definitely better to verify your tokens with a second system. Simply validating the signature just means that the token was generated with your secret. Storing any created tokens in some sort of DB (redis, memcache/sql/mongo, or some other storage) is a fantastic way of assuring that you only accept tokens that your server has created. In this scenario, even if your secret is leaked, it won't matter too much as any generated tokens won't be valid anyway. This is the approach I'm taking with my system - all generated tokens are stored in a DB (redis) and on each request, I verify that the token is in my DB before I accept it. This way tokens can be revoked for any reason, such as tokens that were released into the wild somehow, user logout, password changes, secret changes, etc.
2.) This is something I don't have much experience in and is something I'm still actively researching as I'm not a security professional. If you find any resources, feel free to post them here! Currently, I'm just using a private key that I load from disk, but obviously that is far from the best or most secure solution.
Here are some things to consider when implementing JWT's in your application:
Keep your JWT lifetime relatively short, and have it's lifetime managed at the server. If you don't, and later on need to require more information in your JWTs, you'll have to either support 2 versions, or wait until your older JWTs have expired before you can implement your change. You can easily manage it on the server if you only look at the iat field in the jwt, and ignore the exp field.
Consider including the url of the request in your JWT. For example, if you want your JWT to be used at endpoint /my/test/path, include a field like 'url':'/my/test/path' in your JWT, to ensure it's only ever used at this path. If you don't, you may find that people start using your JWTs at other endpoints, even ones they weren't created for. You could also consider including an md5(url) instead, as having a big url in the JWT will end up making the JWT that much bigger, and they can get quite big.
JWT expiry should be configurable by each use case if JWTs are being implemented in an API. For example, if you have 10 endpoints for 10 different use cases for JWT's, make sure you can make each endpoint accept JWTs that expire at different times. This allows you to lock down some endpoints more than others, if for example, the data served by one endpoint is very sensitive.
Instead of simply expiring JWTs after a certain time, consider implementing JWTs that support both:
N usages - can only be used N times before they expire and
expire after certain amount of time (if you have a one use only token, you don't want it living forever if not used, do you?)
All JWT authentication failures should generate an "error" response header that states why the JWT authentication failed. e.g. "expired", "no usages left", "revoked", etc. This helps implementers know why their JWT is failing.
Consider ignoring the "header" of your JWTs as they leak information and give a measure of control to hackers. This is mostly concerning the alg field in the header - ignore this and just assume that the header is what you want to support, as this avoids hackers trying to use the None algorithm, which removes the signature security check.
JWT's should include an identifier detailing which app generated the token. For example if your JWT's are being created by 2 different clients, mychat, and myclassifiedsapp, then each should include it's project name or something similar in the "iss" field in the JWT e.g. "iss":"mychat"
JWT's should not be logged in log files. The contents of a JWT can be logged, but not the JWT itself. This ensures devs or others can't grab JWT's from log files and do things to other users accounts.
Ensure your JWT implementation doesn't allow the "None" algorithm, to avoid hackers creating tokens without signing them. This class of errors can be avoided entirely by ignoring the "header" of your JWT.
Strongly consider using iat (issued at) instead of exp (expiry) in your JWTs. Why? Since iat basically means when was the JWT created, this allows you to adjust on the server when the JWT expires, based on the creation date. If someone passes in an exp that's 20 years in the future, the JWT basically lives forever! Note that you automatically expire JWTs if their iat is in the future, but allow for a little bit of wiggle room (e.g 10 seconds), in case the client's time is slightly out of sync with the servers time.
Consider implementing an endpoint for creating JWTs from a json payload, and force all your implementing clients to use this endpoint to create their JWTs. This ensures that you can address any security issues you want with how JWTs are created in one place, easily. We didn't do this straight off in our app, and now have to slowly trickle out JWT server side security updates because our 5 different clients need time to implement. Also, make your create endpoint accept an array of json payloads for JWTs to create, and this will decrease the # of http requests coming in to this endpoint for your clients.
If your JWT's will be used at endpoints that also support use by session, ensure you don't put anything in your JWT that's required to satisfy the request. You can easily do this if you ensure your endpoint works with a session, when no JWT is supplied.
So JWT's generally speaking end up containing a userId or groupId of some sort, and allow access to part of your system based on this information. Make sure you're not allowing users in one area of your app to impersonate other users, especially if this provides access to sensitive data. Why? Well even if your JWT generation process is only accessible to "internal" services, devs or other internal teams could generate JWTs to access data for any user, e.g. the CEO of some random client's company. For example, if your app provides access to financial records for clients, then by generating a JWT, a dev could grab the financial records of any company at all! And if a hacker gets into your internal network in anyway, they could do the same.
If you are are going to allow any url that contains a JWT to be cached in any way, ensure that the permissions for different users are included in the url, and not the JWT. Why? Because users may end up getting data they shouldn't. For example, say a super user logs into your app, and requests the following url: /mysite/userInfo?jwt=XXX, and that this url gets cached. They logout and a couple of minutes later, a regular user logs into your app. They'll get the cached content - with info about a super user! This tends to happen less on the client, and more on the server, especially in cases where you're using a CDN like Akamai, and you're letting some files live longer. This can be fixed by including the relevant user info in the url, and validating this on the server, even for cached requests, for example /mysite/userInfo?id=52&jwt=XXX
If your jwt is intended to be used like a session cookie, and should only work on the same machine the jwt was created for, you should consider adding a jti field to your jwt. This is basically a CSRF token, that ensures your JWT can't be passed from one users's browser to anothers.
I don't think I'm an expert but I'd like to share some thoughs about Jwt.
1: As Akshay said, it's better to have a second system to validate your token.
a.: The way I handle it : I store the hash generated into a session storage with the expiricy time. To validate a token, it needs to have been issued by the server.
b.:There is at least one thing that must be checked the signature method used. eg :
header :
{
"alg": "none",
"typ": "JWT"
}
Some libraries validating JWT would accept this one without checking the hash. That means that without knowing your salt used to sign the token, a hacker could grant himself some rights. Always make sure this can't happen.
https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
c.: Using a cookie with a session Id would not be useful to validate your token. If someone wants to hijack the session of a lambda user, he would just have to use a sniffer (eg : wireshark). This hacker would have both information at the same time.
2: It is the same for every secret. There is always a way to know it.
The way I handle it is linked to the point 1.a. : I have a secret mixed with a random variable. The secret is unique for every token.
However, I am trying to understand the best practices for exactly how
and to what extent the token should be validated, to make a truly
secure system.
If you want the best security possible, you should not blindly follow best practices. The best way is to understand what you're doing (I think it's ok when I see your question), and then evaluate the security you need. And if the Mossad want to have access to your confidential data, they 'll always find a way. (I like this blog post : https://www.schneier.com/blog/archives/2015/08/mickens_on_secu.html )
Lots of good answers here. I'll integrate some of the answers I think are most relevant and add some more suggestions.
1) Should JWT token validation be limited to verifying the signature of the token itself, relying on the integrity of the server secret alone, or accompanied by a separate validation mechanism?
No, because of reasons unrelated to the compromise of a token secret. Each time a user logs in via a username and password, the authorization server should store either the token that was generated, or metadata about the token that was generated. Think of this metadata as an authorization record. A given user and application pair should only have one valid token, or authorization, at any given time. Useful metadata is the user id associated with the access token, the app id, and the time when the access token was issued (which allows for the revocation of existing access tokens and the issuing of a new access token). On every API request, validate that the token contains the proper metadata. You need to persist information about when each access tokens was issued, so that a user can revoke existing access tokens if their account credentials are compromised, and log in again and start using a new access token. That will update the database with the time when the access token was issued (the authorization time created). On every API request, check that the issue time of the access token is after the authorization time created.
Other security measures included not logging JWTs and requiring a secure signing algorithm like SHA256.
2) If JWT signature verification is the only means of validating tokens, meaning the integrity of the server secret is the breaking point, how should server secrets be managed?
The compromise of server secrets would allow an attacker to issue access tokens for any user, and storing access token data in step 1 would not necessarily prevent the server from accepting those access tokens. For example, say that a user has been issued an access token, and then later on, an attacker generates an access token for that user. The authorization time of the access token would be valid.
Like Akshay Dhalwala says, if your server-side secret is compromised, then you have bigger problems to deal with because that means that an attacker has compromised your internal network, your source code repository, or both.
However, a system to mitigate the damage of a compromised server secret and avoid storing secrets in source code involves token secret rotation using a coordination service like https://zookeeper.apache.org. Use a cron job to generate an app secret every few hours or so (however long your access tokens are valid for), and push the updated secret to Zookeeper. In each application server that needs to know the token secret, configure a ZK client that is updated whenever the ZK node value changes. Store a primary and a secondary secret, and each time the token secret is changed, set the new token secret to the primary and the old token secret to the secondary. That way, existing valid tokens will still be valid because they will be validated against the secondary secret. By the time the secondary secret is replaced with the old primary secret, all of the access tokens issued with the secondary secret would be expired anyways.
IETF have a RFC in progress in the oAuth Working Group see : https://tools.ietf.org/id/draft-ietf-oauth-jwt-bcp-05.html
I am working on asp.net web api 2 and used JWT for authentication. The application is working fine as it generates token on login request from user, and then user can use that token for subsequent request. But I have some security concerns like
What if the token is stolen from user's browser, How can server detect a valid request among two requests sent from two different computers.
When user will sign out, how server can detect that this particular token is now invalid/loggedout. As I read about log out, it is merely deletion of token from client browser, so stolen token will still be there, requesting from other pc.
How can server revoke a token when expiration period reached?
Please comment if my question is not clear.
Please find the answers as below:
1) Access tokens like cash, if you have it then you can use it, if you have valid access token there is no way to identify if the request is coming Authorized party or not, thats why HTTPS must be used with OAuth 2.0 and bearer tokens.
2) Self contained tokens like JWT are not revocable, so there is no DB checks and this is the beauty of it, you need to leave those tokens until they expire. If you used reference tokens then you will be able to revoke them, but the draw back for this approach is hitting the DB with each API call to validate the token.
3) Already answered in part 2.
You can check my series of posts about this topic using the below links:
Token Based Authentication using ASP.NET Web API 2, Owin, and
Identity.
AngularJS Token Authentication using ASP.NET Web API 2.
JSON Web Token in ASP.NET Web API 2 using Owin.
When it comes to JWT revocation the general idea seems to be either that:
it simply can't be done
or it can be done, but it goes against the stateless nature of JWT.
I generally don't agree with either. First JWT is just a token format (Learn JSON Web Tokens), yes it can be used to shift some state from servers to clients, but that does not impose any restriction on what we can and should do to consider them valid from the point of view of our application.
Second, if you understand the implications and the associated cost of implementing revocation functionality and you think it's worthwhile to use self-contained tokens instead of alternatives that could simplify revocation but increase the complexity elsewhere then you should go for it.
Just one more word on the stateless thing, I think I could only agree to it in the remote chance that the application receiving and validating tokens does not maintain any state at all. In this situation, introducing revocation would mean introducing a persistent store where one did not exist before.
However, most applications already need to maintain some kind of persistent state so adding a few more bits to track blacklisted/invalid tokens is a non-issue. Additionally, you only need to track that information until the token expiration date.
Having covered the general theory, lets go through your individual questions:
If your security requirements mandate that you need to employ additional measures to try to detect malicious use of a token then you're free to do so. A simple example would be blacklisting a token if you detect usage of the same token coming from very different geographical locations.
With support for token revocation in place the application logout scenario would just need to include a step to blacklist the associated token.
I may be missing something here, but if the token expiration time was reached the regular process to validate a JWT would already include a check to make sure that the token was not yet expired.
I'm new to OAuth, and although I have scanned through many documents, I don't seem to have yet a good architecture / design to a secure web application, answering most/all of OWASP Top Ten
My newbie questions are
Why can't I just rely purely on OAuth? why do a user needs credential in my own application?
If I do, do I need hash / salt anything if I save it? I don't store any passwords, but what about tokens?
I still need to persist the users so they won't login everytime, (like in OS) - do I
Somehow use the OAuth token (save it? does it make even sense)?
Or use the plain old httpOnly secure cookie (if so, what happens if they log out of the Oauth provider? shouldn't I in this case ignore my cookie and let them log out?
How do I implement logging out? I can't force them to log out of the OAuth provider, and if I only delete the httpOnly cookie / invalidate their session locally, is that enough? and security issues?
How do I implement single sign on? I don't want the user, after approving to click again "log in using Facebook / Twitter / Google" I want an effect similiar to SO (page refreshes and "welcomes you back" what are the best practices to do that? Why does SO refreshes the page (I assume it has to do with the fact it needs to be client side, but I don't fully understand how it works to even know what to ask)
I guess I have a lot to learn, but reading on so many potential security issues, and having to master so many different topics seems like a good potential for me missing something that someone later will exploit.
Is using a framework such as Spring Security, or using Lift's built in user management going to save me all this headache? or do I have to know exactly what I am doing to avoid things like Session Fixation, Cross Site Request Forgery, Cross site scripting, Rainbow tables and other things I only remotely get...
Why can't I just rely purely on OAuth?
From a service providers perspective, OAuth is a means of controlling access of third party applications to the business logic. The end user does not have to give out his password to the third party app, and the access can be controlled. For example, the provider could restrict the access to only parts of the service for limited amount of time.
If you write a third party application, there is no strict need for you to have your "own" user artifacts. You can rely on the users that authenticate your application.
You could require that user's have an account with a provider such as Facebook or Twitter and not implement any password stuff yourself.
(You probably need some sort of artifact to represent a user, it should in this case contain information about how that user authenticates your application, for instance an OAuth token, or an OpenID URL).
If I do, do I need hash / salt anything if I save it? I don't store
any passwords, but what about tokens?
Just to clarify, in OAuth a token is typically both a key and a secret, and they are needed in cleartext to sign requests (there are differences here depending on which version of OAuth you use). So you can store them encrypted, as long as it is reversible for you.
I still need to persist the users so they won't login everytime, (like in OS) - do I
somehow use the OAuth token (save it? does it make even sense)?
Yes this makes sense, a token represents your applications access to a specific user's data. Save the token if you want to keep a "session" alive.
How do I implement logging out? I can't force them to log out of the OAuth provider, and if I only delete the httpOnly cookie / invalidate their session locally, is that enough? and security issues?
There is no concept of "logging" out of OAUth, a token either has an expiration time or not. You can of course "log out" by simply choosing to forget the token. The next time you will have to redo the authentication. You cannot force users to invalidate an access token, unless the provider has an API for that.
You could save the token in a cookie, but I would use other unique identifiers for the session you want to keep alive. You can persist the details of the tokens server side. The information you store in your cookie shold make it possible to retrieve the token you need.
How do I implement single sign on? I don't want the user, after approving to click again "log in using Facebook / Twitter / Google" I want an effect similiar to SO (page refreshes and "welcomes you back" what are the best practices to do that? Why does SO refreshes the page (I assume it has to do with the fact it needs to be client side, but I don't fully understand how it works to even know what to ask)
If you save a token in a database, save an ID for that token in a nice secure cookie. When a user goes to your service, use the information in the cookie to make a call from your service, to the service provider, to check if the token is still valid. If so, you have established enough trust for you to "log in" the user in your application without having to go through the pain of the OAuth process again.
And as a side not, StackOverflow uses OpenID and not OAuth for user authentication. OAuth can be used for the same purpose but is mainly a specification for application authorization.
I hope this helped, and don't sell yourself short. This site is for posting questions, not for appearing all-knowing.
I want to understand what token-based authentication means. I searched the internet but couldn't find anything understandable.
I think it's well explained here -- quoting just the key sentences of the long article:
The general concept behind a
token-based authentication system is
simple. Allow users to enter their
username and password in order to
obtain a token which allows them to
fetch a specific resource - without
using their username and password.
Once their token has been obtained,
the user can offer the token - which
offers access to a specific resource
for a time period - to the remote
site.
In other words: add one level of indirection for authentication -- instead of having to authenticate with username and password for each protected resource, the user authenticates that way once (within a session of limited duration), obtains a time-limited token in return, and uses that token for further authentication during the session.
Advantages are many -- e.g., the user could pass the token, once they've obtained it, on to some other automated system which they're willing to trust for a limited time and a limited set of resources, but would not be willing to trust with their username and password (i.e., with every resource they're allowed to access, forevermore or at least until they change their password).
If anything is still unclear, please edit your question to clarify WHAT isn't 100% clear to you, and I'm sure we can help you further.
From Auth0.com
Token-Based Authentication, relies on a signed token that is sent to
the server on each request.
What are the benefits of using a token-based approach?
Cross-domain / CORS: cookies + CORS don't play well across different domains. A token-based approach allows you to make AJAX
calls to any server, on any domain because you use an HTTP header
to transmit the user information.
Stateless (a.k.a. Server side scalability): there is no need to keep a session store, the token is a self-contained entity that conveys all the user information. The rest of the state lives in cookies or local storage on the client side.
CDN: you can serve all the assets of your app from a CDN (e.g. javascript, HTML, images, etc.), and your server side is just the API.
Decoupling: you are not tied to any particular authentication scheme. The token might be generated anywhere, hence your API can
be called from anywhere with a single way of authenticating those
calls.
Mobile ready: when you start working on a native platform (iOS, Android, Windows 8, etc.) cookies are not ideal when consuming a
token-based approach simplifies this a lot.
CSRF: since you are not relying on cookies, you don't need to protect against cross site requests (e.g. it would not be possible to
sib your site, generate a POST request and re-use the existing authentication cookie because there will be none).
Performance: we are not presenting any hard perf benchmarks here, but a network roundtrip (e.g. finding a session on database)
is likely to take more time than calculating an HMACSHA256 to
validate a token and parsing its contents.
A token is a piece of data which only Server X could possibly have created, and which contains enough data to identify a particular user.
You might present your login information and ask Server X for a token; and then you might present your token and ask Server X to perform some user-specific action.
Tokens are created using various combinations of various techniques from the field of cryptography as well as with input from the wider field of security research. If you decide to go and create your own token system, you had best be really smart.
A token is a piece of data created by server, and contains information to identify a particular user and token validity. The token will contain the user's information, as well as a special token code that user can pass to the server with every method that supports authentication, instead of passing a username and password directly.
Token-based authentication is a security technique that authenticates the users who attempt to log in to a server, a network, or some other secure system, using a security token provided by the server.
An authentication is successful if a user can prove to a server that he or she is a valid user by passing a security token. The service validates the security token and processes the user request.
After the token is validated by the service, it is used to establish security context for the client, so the service can make authorization decisions or audit activity for successive user requests.
Source (Web Archive)
Token Based (Security / Authentication)
This means that in order for us to prove that we’ve access we first have to receive the token. In a real-life scenario, the token could be an access card to the building, it could be the key to the lock to your house. In order for you to retrieve a key card for your office or the key to your home, you first need to prove who you are and that you in fact do have access to that token. It could be something as simple as showing someone your ID or giving them a secret password. So imagine I need to get access to my office. I go down to the security office, I show them my ID, and they give me this token, which lets me into the building. Now I have unrestricted access to do whatever I want inside the building, as long as I have my token with me.
What’s the benefit of token-based security?
If we think back on the insecure API, what we had to do in that case was that we had to provide our password for everything that we wanted to do.
Imagine that every time we enter a door in our office, we have to give everyone sitting next to the door our password. Now that would be pretty bad because that means that anyone inside our office could take our password and impersonate us, and that’s pretty bad. Instead, what we do is that we retrieve the token, of course together with the password, but we retrieve that from one person. And then we can use this token wherever we want inside the building. Of course, if we lose the token, we have the same problem as if someone else knew our password, but that leads us to things like how do we make sure that if we lose the token, we can revoke the access, and maybe the token shouldn’t live for longer than 24 hours, so the next day that we come to the office, we need to show our ID again. But still, there’s just one person that we show the ID to, and that’s the security guard sitting where we retrieve the tokens.
The question is old and the technology has advanced, here is the current state:
JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for passing claims between parties in web application environment. The tokens are designed to be compact, URL-safe and usable especially in web browser single sign-on (SSO) context.
https://en.wikipedia.org/wiki/JSON_Web_Token
It's just hash which is associated with user in database or some other way. That token can be used to authenticate and then authorize a user access related contents of the application. To retrieve this token on client side login is required. After first time login you need to save retrieved token not any other data like session, session id because here everything is token to access other resources of application.
Token is used to assure the authenticity of the user.
UPDATES:
In current time, We have more advanced token based technology called JWT (Json Web Token). This technology helps to use same token in multiple systems and we call it single sign-on.
Basically JSON Based Token contains information about user details and token expiry details. So that information can be used to further authenticate or reject the request if token is invalid or expired based on details.
When you register for a new website, often you are sent an email to activate your account. That email typically contains a link to click on. Part of that link, contains a token, the server knows about this token and can associate it with your account. The token would usually have an expiry date associated with it, so you may only have an hour to click on the link and activate your account. None of this would be possible with cookies or session variables, since its unknown what device or browser the customer is using to check emails.