Comments (12)
This is how I reissue the same token updating times. I catch the 'ExpiredException' and then I try to decode again with a huge leeway:
public static function refresh($token) {
try{
$decoded = JWT::decode($token, JWT_SECRET, ['HS256']);
//TODO: do something if exception is not fired
}catch ( \Firebase\JWT\ExpiredException $e ) {
JWT::$leeway = 720000;
$decoded = (array) JWT::decode($token, JWT_SECRET, ['HS256']);
// TODO: test if token is blacklisted
$decoded['iat'] = time();
$decoded['exp'] = time() + self::$offset;
return JWT::encode($decoded, JWT_SECRET);
}catch ( \Exception $e ){
var_dump($e);
}
}
from php-jwt.
I'm not sure if my way around this is correct, but I'll air it for opinions anyway.
What I do is issue a Token on successful authorization, with an hour validity. Then on every subsequent I check the token, and then create a new token return it to the client and save it to the file-system, overwriting the previous one. This way, as long as the user remains active their token will never be out of date.
from php-jwt.
Tokens are just Base64 encoded data with a signature. You can access header and payload with something like following:
list($header, $payload, $signature) = explode(".", $token);
print base64_decode($header) . "\n";
print base64_decode($payload) . "\n";
from php-jwt.
Because i run into same problem, i used little bit different solution
try {
$data = JWT::decode($accessToken);
} catch (ExpiredException $e) {
\Firebase\JWT\JWT::$timestamp = 0;
$data = JWT::decode($accessToken);
}
...
it's little bit better, because if you have non expiring refresh token, which can gain new access token, then you don't have to worry which leeway is enough, cause the condition is ($timestamp - static::$leeway) >= $payload->exp
, so this solution will success with any exp
higher then zero.
from php-jwt.
Im worried about how users above are using JWT.
JWT is meant to be stateless. They are signed - so they are immutable.
They reason why we should use them is to NOT check the storage on the server side.
// incomming JWT
if isValid(JWT)
data = getData(JWT)
// further checks (authorization) and execute requested action
else
return non success 401 Unauthorized
If you request f.e. a database to check if the JWT is valid on EVERY request
then you should not use JWT.
Refesh:
If a token is not valid then you create a NEW one.
Ofc you could reuse the data inside the JWT.
BUT this would mean you have to check if nothing else failed.
In this repo you are lucky: ExpiredException
gets thrown last. Means all other checks has been passed - so f.e. the signature is valid.
BUT this does NOT mean you should reuse the data from the invalid token.
Few updates later the ExpiredException
gets thrown at the beginning of ::decode
and all of you are using non-validated data from a manipulated JWT.
What you do if the token has been expired?
You return an error response.
The client that requested the action now has to check if and WHY the action got denied.
Draft:
// client request
jwt = this->getJWT() // load JWT from storage
client = new HttpClient()
client->setUrl(url) // set your request target (f.e. get list of product items ...)
client->setAuthorizationHeader(jwt)
response = client->get()
if response->isSuccess()
data response->getBody()
// ... success handling ...
else
// request denied
if response->getStatusCode === 401
// invalid token server response
// lets get a new one
refreshToken = this->getRefreshToken() // load refresh token from storage
client = new HttpClient()
client->setUrl(this->getServerRefreshUrl())
client->setAuthorizationHeader(refreshToken)
response = client->get()
if response->isSuccess()
// refresh-request success
// received new access- AND refresh-token from server
// store new tokens
data = response->getBody()
jwt = data[access_token]
resfreshToken = data[refresh_token]
this->saveJWT(jwt) // overwrite existing
this->save(refreshToken) overwrite existing
// execute actual request again (see above)
else
// refresh-request failure
// need to login to receive new JWT and refresh token
loginCredentials = this->getLoginCredentials()
client = new HttpClient()
client->setUrl(this->getServerLoginUrl())
response = client->post(loginCredentials)
if response->isSuccess()
// login-request success
// received access- AND refresh-token from server
// store tokens
data = response->getBody()
jwt = data[access_token]
resfreshToken = data[refresh_token]
this->saveJWT(jwt) // overwrite existing
this->save(refreshToken) overwrite existing
// execute actual request again (see above)
else
// invalid login attempt
// ... handle invalid login credentials ...
else
// response is not 401 --further error handling (404? ...)
Ofc this needs to be written clean in functions|methods.
To answer the original question: no, you should not reuse the JWT data.
Except you can make sure that all other checks have been made - so f.e. the signature on the JWT was valid.
The server creates a new JWT and MUST use the current data from the storage.
This f.e. would prevent using expired or modified data like permissions (that has been revoked|changed).
from php-jwt.
@fjaguado so if the token was revealed,it will be used forever?
from php-jwt.
public static function refresh($token) { try{ $decoded = JWT::decode($token, JWT_SECRET, ['HS256']); //TODO: do something if exception is not fired }catch ( \Firebase\JWT\ExpiredException $e ) { JWT::$leeway = 720000; $decoded = (array) JWT::decode($token, JWT_SECRET, ['HS256']); // TODO: test if token is blacklisted $decoded['iat'] = time(); $decoded['exp'] = time() + self::$offset; return JWT::encode($decoded, JWT_SECRET); }catch ( \Exception $e ){ var_dump($e); } }
I have tested this code and it generates a new different token. I thought that this code refreshes me the lifetime of my original token. But it generates a new one for me.
No way to refresh the same token without changing it?
from php-jwt.
You probably shouldnt.
The better thing and apparently more standard is to have a seperate second token in storage that is only allowed to refresh the main token.
So you have a token that expires in say ... an hour. You also have a second token that expires in 2 hours, but only has permission to refresh the main token. This will give the client an hour after their token expires to request a refreshed token using the "refresh" token that is still ok.
This interaction allows you to set up a workflow where if a client is idle for longer than a certain period, their tokens expire, but while they are active, their tokens will be kept up to date.
from php-jwt.
i would also like to know how to reissue a jwt token within datapower.
from php-jwt.
@ashraful88 That's probably not best practice. Check this out: http://stackoverflow.com/questions/3487991/why-does-oauth-v2-have-both-access-and-refresh-tokens
from php-jwt.
@williamqian No
this line
$decoded['exp'] = time() + self::$offset
refer to expiration date with $offset
added to current time in seconds.
from php-jwt.
### ### ### ### good
from php-jwt.
Related Issues (20)
- JWT::createPemFromModulusAndExponent incorrect return value HOT 6
- Support for DPoP HOT 1
- Can not decode EXP token, is there a way? HOT 3
- Micorsoft Entra ID and msal-browser/2.37.1 error validation access token HOT 1
- Support for Millisecond timestamps HOT 2
- how to destroy jwt token on logout at server side php HOT 2
- CakePHP Views, You are not authorized to access that location HOT 1
- Issues with composer autoloader in Symfony project HOT 2
- rate limit cache expiration is not working as expect in CachedKeySet.php HOT 7
- Error when decoding a JWT with JWK set HOT 1
- Is there way way to load the token from Cookie? HOT 1
- Uncaught Error: Firebase\JWT\JWT::decode(): Argument #3 ($headers) cannot be passed by reference in HOT 10
- Cannot use JWK::parseKey for kty=='oct' HOT 4
- Firebase PHP-JWT Key/Algorithm Type Confusion HOT 1
- Wrong warnings when invalid key supplied in openssl_sign
- Error when parsing set of JWK keys which contain unsupported algorithms
- الرموز المميزه HOT 3
- Class "Firebase\JWT\Key" not found HOT 1
- Verifying JWK with one out of multiple keys, where one of the keys is a HS256 key HOT 1
- Update Return type of JWT::urlsafeB64Decode HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from php-jwt.