I am using JWT's to authenticate my API server. The JWT is issued by an external auth server (in this case keycloak) and have a typical expiration time of ~5 minutes (IIRC), the frontend should then use these tokens to make requests to the API.
I have been trying to check the expiry date of the token on the frontend, before making each request. If the token is expired, I use the refresh token to first get a new auth token then make the request.
The basic workflow is:
== Login ==
1. Get Auth token
2. Store expiry (exp) date (this is in UTC seconds)
== API Request ==
1. Check expiry date (isExpired = expiryDate <= Math.floor(Date.now() / 1000))
2. If OK => make request
3. Otherwise, refresh auth token and redo request.
Is it bad practice to check the date like this? What is an alternative method to ensuring requests succeed?
I ask because I have seen problems on some machines where the expiration check always returns false (it is not expired)...
The problem with relying with a frontend check is you have no control over the local time on the user's machine, which could be wrong.
A more robust way could be to make the request as usual and if the token has expired return an error message from the server. On each request, if the error message is received from the server, the client can then trigger the refresh process and then resubmit the original request with the new token.
The best way to handle that situation is that the front should only check if the expiry date set in the backend is expired or not. Usually the error return just like this {name: 'TokenExpiredError', message: 'jwt expired'}. If that is the case, then that's the time that you will make another login request.
I feel, a frontend check will be a good instead of making a request with expired token and do the refresh mechanism post that. I agree, the local time may differ. To make sure that it does work if we use UTC in token we can easily validate in any timeZone.
Related
I'm using the AWS-Amplify library in my single page application. The user login is managed by Amazon-cognito.
Client - API requests contain JWT (header - Bearer Authentication).
Server side(node.js) - receives the token and validates it (via jsonwebtoken).
This works well to the point that there is no user activity for a long period (over an hour).
I simulated this scenario. In my client side app i was inactive, and before sending the request i checked the state of the session:
const session = await Auth.currentSession();
if (!session.isValid()) {
...
}
The isValid method returns always true, because the expiration time of the token is automatically extended. When this token is being sent to the server, the authentication fails.
How can i overcome the inactivity issue, without workarounds (timers etc...)?
I've implemented a JWT authentication for my rest api.
I'm struggling to understand how to hide the token in JavaScript.
For example, all the clients (web browser and mobile phone app) will call my api with an header:
Authorization': 'Bearer eyJ0eXAiOXXXXXXX
In PHP it makes sense, but in JavaScript "everyone" can see the token. So what's the point of having one?
Even if the token expires after X minutes, all you need to do is get the new token every X minutes, and you have access to the same API.
Did I miss something?
Of what I have understand of Token, they are used to help the server to know 'who is sedding this request' and if this person has the right to.
they are made for simplification of this process, not for security.
If you don't use Token, I think, that means you have to send and check password at each request.
But yes, the information inside is not hidden, as you read Here:
Do not put secret information in the payload or header elements of a JWT unless it is encrypted
I know that you can encrypt your token, but I've never done this, so I can't say much about it.
A solution is using SSL/HTTPS for security.
I have a .Net Core2 webapi in which I have a user/pass authentication to issue a short lived jwt (5 min) which includes a long session revocable refresh token. When the jwt expires, the webapi checks if there is a refresh available and if there is, it returns the new token
On the client side, I want to place a global hook on any ajax calls to catch the case where a 401 is returned, but with a new token. This hook would simply reset the token and resubmit the request.
Is the best way to do this ajaxSetup? Example would be appreciated. Any issues anyone can see with this approach?
I'm creating an app using Angular 1.5.8 and Laravel 5.2. I'm using a library by Luca Degasperi to create Token Based Auth
Via Angular I make a call and I receive access_token, TTL and refresh_token. I store access_token and refresh_token on localStorage. I can use access_token that I get to make calls to get some data from my API. When token expires I'm getting a message that the token is invalid with 401 code
So my question is how to check if the token is still valid before I send a http request to my API? What is the best way to refresh the token? Ok, I can send a request for the refresh my token to https://my.api/oauth?grant_type=refresh_token&refresh_token=f32j93201h00xpaf1, but how to check it before every http request? Can I repeat the call if the response code is 401? And how?
Please, give me some advice :)
I had exactly the same problem few days ago. Angular Error response interceptor is all you need ;) Also, this article was really helpful
You cannot. You have to check against a login. Therefore it's just a re-login.
I guess that if you get a 401, your refresh token is already done.
Though I guess that you can join that refresh token with all your requests? I might be wrong.
Ensure that your token TTL is always up to date by refreshing its TTL from time to time (like with requests to your API).
Can't you use the TTL to determine if the token is still active? When you store your tokens in local storage you can add the date/time the token was stored and each time you go to make a service call you can check the TTL against the time the token was stored.
It will only tell you when it expires, though, and not if the token was invalidated for some other reason.
I am interested in how you would determine using XMLHttpRequest if the user had already authenticated with a server? I can send my request and return data but if I refresh the page and request the data again my logon form is firing even though the session time out has not expired.
Any thoughts?
Thanks
Chris
There are a couple options here. Often times a serve will respond with a login form to any unauthenticated request. Thus, if you're making an AJAX request that fetches JSON, you can just look at the content-type of the response, ala xhr.getResponseHeader('Content-Type'). Authenticated responses should be something like application/json, while unauthenticated responses will be text/html (or something like that.)
But... you can also look at document.cookie to see if the user has a session cookie defined. While this isn't a bullet-proof check (the cookie may be invalid, or the server may have additional checks in place that could still fail the request), it's not an unreasonable check to do.