I'm new to webdev and have implemented access token & refresh token based authentication in my express project. However, the more I look over the implementation I'm starting to question why access tokens exist when it appears that refresh tokens make them redundant. Perhaps it's just my implementation.
For any task that needs authentication, I send off a cookie with both an access token and refresh token to an auth server. It looks at the access token, and if it is both valid and unexpired, it will send a 200 back and allow any express middleware to continue on.
However if it has expired, it will then query a database to see if a matching refresh token exists and, if so, will send a new access token.
As the lifetime of the access token decreases, the auth server will need to do more database searches to verify the refresh token. At that rate, why bother with the access token and instead why not rely solely on the refresh token? After all, the refresh token can be removed from the database and the authorisation server can reject any requests made with it.
The only reason I can think of the access tokens existing is to reduce how often a page will need to query a database, but that seems too simple. Since I'm fairly new to this, I know I must be missing some larger concept. Can anyone enlighten me?
Related
I understood that Refresh Token is used to get another access token after it expires. But, I am confused about how to use it.So, here is what my code looks like(I am building a app with Twitter API and the app uses Oauth2.0 authorization):
User sends request to my API server with access token and refresh token(stored in cookies)
In my server, when I make request to the Twitter API, first I request with access token--if the request is unauthorized(due to expired access_token) I use refresh token to get another access token and use that to make request.
This 2) codeblock for everytime I make a API request to the Twitter API is infuriating me. What is the better way to write. Am I doing something wrong.
You haven't included your code, so it's impossible to tell what might be incorrect about it. However, the process for using a refresh token is pretty straightforward. See here (under Refresh tokens near the top) and here (at step 5) in the docs.
Essentially, you will make a POST call to https://api.twitter.com/2/oauth2/token with a URL-encoded body. You will include the refresh token and a grant type of refresh_token in that body. Depending on whether your app is a confidential client or not, you'll include the client ID in the body or in the header with a client secret.
Whatever code you are using for the access token should be easily reusable with a few tweaks.
I'm currently working on a project with expressjs. For user authorization I use JWT tokens but until now only access tokens, because I just don't understand them together with a real example. So can somebody explain to me what the steps are the authorization goes through when someone logs into his account.
f.E.:
Refresh and Access Tokens get generated
Token gets stored into database etc.
Thank you in advance and have a great day
User sends a POST request with login credentials
Server authenticates and if successful, returns a JWT (usually in a httpOnly cookie). Server does not store JWTs in a database. The whole point of JWT is that authentication state is stored by the bearer of it.
For subsequent requests to protected endpoints, client needs to attach JWT. Server should check if JWT is expired and whether it has been altered.
Extensions that you might want to think about:
How to refresh JWTs:
There are different refreshing patterns that can be used. For
example, you can check the expiry of the JWT every time that your
server receives a request. If JWT is expiring soon, issue a fresh
JWT.
How to maintain authentication state on client-side without having to log in every time you refresh the page
How to really log a user out:
If you set the expiry as 30 minutes and a user logs out at the 15th minute mark, that JWT can technically still be used to access protected endpoints for another 15 minutes.
I am using Firebase authentication to authenticate users. Whenever, the user is logged in, I get the user's ID token with user.getIdToken(true) and set it on the local storage. With that token in the authorization header, I am requesting my back-end API.
On the back-end side, I am using Firebase admin SDK to authenticate the request and the user with the client-side ID token passed in the request authorization header.
This works for a while. But after some time I get error:
ExpiredIdTokenError: Token expired, 1620908095 < 1620915515
I saw that Firebase refreshes the ID token on its own. But I don't think that's the case. I have looked through the developer tools network tab, and there's also an observer method to check whenever the token has changed => onIdTokenChanged(), but the token is never refreshed.
I couldn't find any information on the Firebase docs either, and I was hoping if you could help me:
How can I generate a token without expiration limit to last until signed out or at least for some more time (1 week maybe)?
If I cannot the set the expiry limit of the token, what steps should I take so that I can send a valid unexpired token when I am request data from my back-end? Do I have to call user.getIdToken(true) every-time and get a fresh token before I request from my back-end API?
The idTokenChanged() observer is a bit misleading. It will fire when the token is refreshed, but the token is only refreshed automatically when you also use other Firebase products (like its database or file storage). In other cases, as you said you should call user.getIdToken(), which will refresh an expired token for you if necessary, everytime you call your API. You don't need to pass true into this method unless you want to have a completely fresh token everytime (which you most likely don't need).
To my knowledge you cannot control the expiration of tokens generated with the client SDK, for that you would need to generate your own tokens on the server.
My simple application written in Javascript is using a service (which is written as a wrapper on Auth0) for authentication. On successful login, if I refresh the home page, application again goes to login page (even if I have stored the access token in cookies)
I also tried to store the access token in browser session storage.
As my index.html is launched, i am checking if my application url contains access token. If there is no access token, I redirect it to login page.
if (((window.location.hash).indexOf('access_token') < 0)) {
location.replace(redirectUrl);
}
On successful login, as url has access token in it, app works fine further.
But next time when I refresh the home page, it don't have access token in URL.
As per my understanding, as I have access token in cookies, it should not ask me for login again as long as token is valid.
It is still asking for login. What should be the strategy should I use to persist the token ?
On logout, I am setting the cookie to expire. Is there any ideal way to do log out other than this?
This can often be troubleshooted with a HAR file capture to follow the trail being left in the authentication flow. However since we don't have that option at this juncture here are a couple things to look at.
Are you using Dev keys in your auth scenario?
Expiry time
Where is the access token being stored?
https://auth0.com/docs/tokens/overview-access-tokens
Currently, you have a somewhat incomplete implementation.
As per my understanding, as I have access token in cookies, it should not ask me for login again as long as token is valid.
Saving token in the cookie storage and local storage does not have any relation with user authentication state. It is just a way of persisting the token and reading the data. In each navigation, you need to read the token and extract the information from the token to make sure user is authenticated.
The architecture you should follow:
Redirect the user to /authorize endpoint if there is no valid token in the application.
Once auth0 finish the user validation, the user will be redirected in the whitelisted callback URL. Make sure this URL is unique and save the token from URL fragments. It is very important to complete the token validation on the client side. Otherwise, it will be a major security issue. https://auth0.com/docs/tokens/guides/id-token/validate-id-token
Redirect the user to the secured URL.
I would highly recommend using auth0 SDK as it mitigates all the security issues including token signature validation using RS256 algorithm.
https://auth0.com/docs/quickstart/spa/vanillajs/01-login
You may find folloiwng thread useful
Why my auth0 token expires when refreshing page or clicking link in my Angular app?
I am fairly new to implementing JWT. I had a few questions while implementing JWT. I am using axios to make requests.
When the user logs in or registers. I get an accessToken, which expires in a few days. I dont have a refreshToken because I think the backend is built on django rest framework.
Now if I get a status code of 401 in a request, I try to check if the token has expired and if yes, then refresh the accessToken, but at times even the refresh token api returns 400 suggesting that this token is also expired, at which point I need the user to log out.
I think this is a bad User Experience, Why is that we cannot refresh the token using old token. Is there a way to keep it from expiring? Can anyone point me to an example which solves the following problem with a correct implementation of axios interceptors?
Since you are using Django rest framework, consider using Djoser with JWT tokens, then djoser sends you access and refresh tokens from the backend. Once the backend preparation is over, follow this simple article to refresh and access tokens automatically from react native. Hope it helps you.
You can create a token which will never expire but that's a bad idea for security reasons. If the token is stolen then someone can always access the user's data. You can set the expiration date in exp claim. Read more here: https://gist.github.com/soulmachine/b368ce7292ddd7f91c15accccc02b8df