-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Access tokens vs refresh tokens? #1105
Comments
Yes that's the thing that confuses me the most, too. While jwt-auth has the possibility to refresh the token if it's expired, it's not doing this by using a seperate refresh token, right? So all I can do is check the token itself for validity and issue another one with the response if it's expired. |
I'm not sure how that helps. I already understand what the difference is, or I think I do. What I'm pointing out, and asking about, is that this package jwt-auth appears to only have refresh tokens and no regular tokens, unless I'm misunderstanding something. There aren't two different types of tokens it can generate as far as I can tell. |
This is what I learned from playing around with it:
public function refreshToken(Request $request)
{
return JWTAuth::refresh($request->only('token')['token']);
}
let now = new Date();
let diff = getDateDiff(now, state.tokenTimeStamp, 'minutes');
let tokenLifeSpan = 1439; // 1 day - 1 min
if (diff > tokenLifeSpan)
{
if (window.refreshingToken)
{
// this is to prevent an endless loop
console.log('refreshingToken...');
return;
}
window.refreshingToken = true;
console.log(`old Token: ${state.token}`);
console.log(`old Token Date: ${state.tokenTimeStamp}`);
// here I start refreshing the token:
axios.post(apiBaseURL+'refreshToken', {token:state.token})
.then(({data}) => {
window.axios.defaults.headers.common = {
'X-Requested-With': 'XMLHttpRequest',
'Authorization': "Bearer " + data ,
};
state.token = data;
state.tokenTimeStamp = new Date();
console.log(`new Token: ${state.token}`);
console.log(`new Token Date: ${state.tokenTimeStamp}`);
window.refreshingToken = false;
// then I do the API call once more, after having made sure the new token is set properly:
dispatch('patch', {id, field, value});
});
console.log('stop here');
return;
} |
I'm not sure why you think you need to pass a date with the token. Tokens already have their expiry date stored within them. One way to get it is with the jwt-decode package: import jwtDecode from 'jwt-decode';
const decoded = jwtDecode(accessToken);
const expiresAt = new Date(decoded.exp * 1e3); And then just compare the current date with But yes, I'm already using similar logic to transparently refresh a token if expired before making the API call. |
I looked over the JWT specification and you're right that there's no such thing as a special refresh token. So I think this ticket is actually asking exactly what I asked in #1146: how can I make a token which cannot be refreshed? I guess it'd have to be a change to the logic in either the refresh functionality in this package, or a higher-level change to the logic in the refresh middleware, which would only allow a token to be refreshed if it has a |
@mesqueeb That seems correct. I really wish that were explained in the wiki. The tiny section on refreshing tokens doesn't really tell us much. Especially since this single token approach seems to unlike most other JWT services. |
@tremby he is referring the new Date/Time on the client side as client can not decode the token and can only know how long the token will live which also has to be disclosed by the server |
@akkhan20: I think I must be misunderstanding you. I don't know why you're saying the client cannot decode the token. The client can absolutely decode the token. I pointed out how a couple of messages back. |
@tremby jwtDecode(accessToken) will never give you a decoded token with its parameters though u can give it a try and please report if it do coz that will be a massive security issue. |
What are you talking about? JWT payloads are just base64url-encoded, not encrypted. https://jwt.io/introduction/#payload |
@tremby the access token generated by this package is encrypted with a secret key on the server that client would never know about so it cant be decrypted on the client and what's the point of an access token that a client can read, isn't it that anyone can generate one alike if they know what information it consists of? The site you referred to also consists of a debugger and you can generate a token through this package and try decrypting it with that without the jwt_secret on the server. |
Go and read the specifications, both of JWT and of HMAC. The only thing happening cryptographically is signing the token. The payload is not encrypted. There's nothing wrong with the client reading their own access token; they already know who they are. No, a user cannot modify or create a new valid access token, because they don't have the secret key and so can't sign the access token. This is a waste of my time, and off topic, and I won't respond to you any more. |
@tremby so as it stands at the moment, a refresh token IS an access token, so there are no tangible "refresh tokens".. just that you can refresh a token using an existing token (given it's within the required refresh_ttl) Having said that, I have been thinking a while that this would be better to have a distinctly separate "refresh_token" that is merely used to retrieve an access token. And I'll be looking at this for the (1.1 / 2.0) release Does that make any sense? @akkhan20 as @tremby has said, I think you need to do a little reading :) https://scotch.io/tutorials/the-anatomy-of-a-json-web-token |
Sounds good. I suppose it might be possible to hack it in right now, by adding a custom "refreshable" claim to a token, and refusing to refresh it if that claim is not present. But yeah, it'd be great if this were built in. |
@tymondesigns thanks for the reference i get it now and @tremby thanks for pointing out the incorrect concept |
Man this is so confusing. The JWT specification doesn't even include the concept of a refresh token, yet many resources talk about it as if its part of JWT. Apparently refreshing tokens is a custom job, and can be done in many ways. I came to this package assuming there exist "refresh tokens", but couldn't find it after digging and digging through the source code, and documentation (although small). My suggestion is to add a "refresh tokens" page to the wiki explaining that there are no refresh tokens, and that the refreshing is done using the original access token. |
@boukeversteegh agreed. This odd concept was by far the largest hurdle to using this package. There should be solid examples and explanations in the docs. |
As I know access tokens and refresh tokens should be stored differently too on the client side. Access tokens can be "not as securely" stored as refresh tokens. What happens if let's say hacker gets access token from you? They can refresh and refresh it forever am I right? Can anyone explain it to me why we only have access tokens here and not using refresh tokens? I think it's very insecure... |
For anyone landing on this page being confused as "the original specs did not specify a separate refresh token" . Apparently this was considered a major security issue. An access token is then stored in either cookie or localStorage, both are prone to CSRF attacks. anyone can use this token to refresh when stolen and use it "forever". |
It's unsecure to store access_token persistent in the browser. It should be stored in memory and requested on every app startup. The refresh_token is different and should be stored in the only one secure place in the browser - in the httpOnly cookie (better with path like /api/auth/refresh). |
Is there any concept of access tokens vs refresh tokens in the context of jwt-auth?
In resources I am reading about JWT, they appear to be separate things, but as far as I can tell there's only one kind of token being handed out in jwt-auth. There's probably something here I'm not understanding.
The text was updated successfully, but these errors were encountered: