Best practices for server-side handling of JWT tokens [closed] - security

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

Related

How safe is an acess token?

I have been reading about OAuth 2.0 Authorization Code flow to protect APIs in microservices architectures but I dont understand how an access token issued by the Auth Server is supposed to protect an API hosted in another server.
Is that same access token also kept in the API and when the client tries to access it with the access token issued by the Auth Server, the API checks if contains it? If so, does that mean that the access token is sent both to client and the protected API in the authentication process?
I hope to have explained my problem well. Thanks in advance.
Anunay gave a pretty good analogy of how JWTs work at a high level as portable, trustable identifier, but since OAuth supports more than just JWT authentication it might warrant sharing a bit more detail.
Token introspection
In your question you rightly assumed that tokens need some way of being trusted, and that one such way would be to store the token in a private database and do a lookup whenever a token is presented to determine its validity. You would absolutely be able to instrument a valid OAuth server using a method like this by issuing the token using whatever form you wish and writing an introspection endpoint that performs the lookup. The OAuth spec is intentionally abstract so that the functional behavior of token introspection can take many forms.
One of the reasons for this level of abstraction is because while storing the tokens for direct lookup might be easy, it means that you have to store copies of these tokens in some form in a private database for comparison. This storage would in turn make you a honeypot for bad actors, both internally and externally, who would seek to impersonate your users en-masse. It's for this reason that many implementations of OAuth prefer to issue and validate tokens using public/private key encryption instead of direct lookups. This process is very much like the one Anunay described in his comment in that it issues tokens that are signed with a private key and verified with a public one. With this process, you no longer need to keep everyone's token in a private database, and instead simply need to secure private and public keys that are used to sign and verify tokens respectively.
JSON Web Tokens (JWTs) and reducing number of introspection calls
Anunay's response specifically referred to a common token structure that is generated using public/private key encryption and issued to users, JSON Web Tokens. These tokens are structured in such a way that they include the user information a backend service might need like the User ID, email address, and sometimes more, in a raw format that is directly readable to the backend API. In addition to this raw information however, JWTs include a duplicate copy of the data, but this duplicate copy is private-key encrypted. In order to trust a JWT token, all you have to do is use the public key and ensure that the private-key encoded payload is verifiable by applying the public key to the raw payload. Since public keys rarely change, many backend services cache the keys used for verification and elect not to do a token introspection on the issuing server since they already can verify the payload. This is how you'd optimize throughput on backend services that are protected via OAuth.
Since public keys can only be used to verify payloads and not produce them, these public keys are often broadcast by the servers that issued the tokens allowing anyone to "trust" the tokens it issues if they so choose. To learn more about this process, I'd recommend you research OpenID Connect.
Access token can be understood as an passport that government issue to the citizen based on proof of identity.
When you take it to another country, they look at the document and trust it because they trust the country and you because you are the holder of that document with you details.
They trust the fact that passport cannot be fiddled with and allow you entry
Now for access token, in very simple terms, authorization server verifies the user. Once verified it issues the user a JWT token (Access Token). This token is signed with private key. It has your details and is encoded along with signature. Now you can take this token to any third party who has got the public key and trust the authorization server. Now when you share the access token with this third party, it use public key to verify the token and check for expiry. If valid it allows you in.
So API doesn't really need to talk to auth server or keep any details about the token. All its needs is a public key to decode the token.
Now there are two important things. One if you ever let loose your access token, or some one who is not intended to get hold of your token gets it, he can do what ever he wants and auth server will not be able to do much. However as you see this approach reduces the chattiness of the systems specially microservices.
So to address this we limit the expiry of access token. Like passport, it comes with expiry. Shorter you keep it,user have to go and get the token refreshed with auth server. Every time he does so, auth server gets a change to verify creds and other details. If they do not match access token will not be refreshed.

JWT advantages over simple randomly-generated tokens in database?

Let's say I have a typical CRUD API for a web application. I need to authorize users by a token, check user roles, etc.
Is there any reason why I should consider JWT over storing a randomly-generated token in a table like tokens(token, refresh_token, expiration_date)?
In my opinion, JWT is adding more complexity here:
Additional code to handle encoding/decoding
Need to store JWT secrets and keys
Token revocation problem
I have to hit a database to check user roles(although I can include them in a payload, there's also other stuff that I should check in my application), so no advantages here. The only benefit I can see here is that I can check token expiration data without hitting a database.
At the same time storing a randomly-generated token in a database is a dead-simple solution.
Am I missing something?
JWTs are often misunderstood. The main benefit they provide is statelessness. If you go to your database to query privileges upon each request anyway, that is pretty much lost, if not from a theoretical but from a practical point of view.
They are typically not stored in http-only cookies, which makes them vulnerable to XSS, but at the same time allows Javascript clients to read the payload (eg. who is logged in, what privileges they have and so on). Not being stored in cookies also allows them to be sent to different origins, which is pretty much the only reason they should not be stored in a http-only cookie (if and only if you understand and accept the risks of this).
JWTs are in no way better or magically more secure than plain old random session tokens - quite the opposite in most cases, especially that it is often overlooked that as opposed to server-side sessions, JWT payload is plaintext. It is protected against tampering by message authentication, but not protected against the user having a look, which sometimes might become an issue.
If you don't need the features above (statelessness, access from javascript), you should just not have the additional complexity of a JWT, you just need a plain old session then.
First thing you need to consider is who will generate the token.
In case of JWT, a valid OAUTH provider will generate the token. The benefits are as follows,
you can validate the legitimacy of the token, which will include checks for following,
a. audience
b. expiry
c. issued at
d. not before date
e. issuer
you can check the issuer based on just the public key which would avoid a network trip to another remote server such as database.
you can inject any payload which can include a userinfo, email, role or any custom attributes.
for a standard OAUTH JWT, you can test using common providers such as 'Okta'. As opposed to your custom generator, where you will have to provide a user a mechanism to retrieve such a token.
as far as the code to check, the JWT is quite straightforward with 3 parts separated by a "period". But there are libraries in java and other languages which can do the parsing for you - com.auth0, specifically jwt and rsa which will let you do the parsing and verification.
your code will be compliant and easily portable to another provider.

Should I reuse OAuth 2.0 access tokens?

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.

ASP.Net Web Api 2, json web token, logout and ensure that the server should not authenticate token anymore

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.

What is token-based authentication?

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.

Resources