Skip to content
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

Laravel Passport Personal Token failing Validation (exp=0) #47

Closed
gbdematos opened this issue Aug 23, 2016 · 28 comments
Closed

Laravel Passport Personal Token failing Validation (exp=0) #47

gbdematos opened this issue Aug 23, 2016 · 28 comments

Comments

@gbdematos
Copy link

I'm trying to create a Personal Access Token to use on Postman.

I followed the same steps as the video from "What's new in Laravel 5.3" where Taylor does that, but I keep getting "Unauthorized" on Postman...

By copying and pasting the generated token on jwt.io, I'm getting "exp" value = 0. Trying to get to the root of the error, I found out that on the "validation" process, it fails exactly on the "exp" validation.

Does anyone have any idea what is happening?

My topic on Laracasts:
https://laracasts.com/discuss/channels/laravel/laravel-passport-personal-token-failing-validation-exp0

Another user with the same problem:
https://laracasts.com/discuss/channels/laravel/laravel-passport-and-postman-gets-all-the-time-unauthorised

@Jonastouw
Copy link

Jonastouw commented Aug 23, 2016

I ran into the same issue, and finally figured out how to make it work. The expiry date is set to now + 100 years in Passport.php, line 167.

return static::$tokensExpireAt
? Carbon::now()->diff(static::$tokensExpireAt)
: new DateInterval('P100Y');

If you set it to, i.e., P1Y, it is working.
Something like:

return static::$tokensExpireAt
? Carbon::now()->diff(static::$tokensExpireAt)
: new DateInterval('P1Y');

The same holds true for the refresh token a few lines below:

return static::$refreshTokensExpireAt
? Carbon::now()->diff(static::$refreshTokensExpireAt)
: new DateInterval('P1Y');

And also in PassportServiceProvider.php line 84, concerning the Personal Tokens:

$server->enableGrantType(new PersonalAccessGrant, new DateInterval('P1Y'));

I guess the 100 years DateInterval yields an int (seconds) somewhere along the way that the exp value is not expecting, setting it to zero and invalidating it. Or it might be some Windows only issue. With these edits it's working and we can move on with this awesome package!

@gbdematos
Copy link
Author

@Jonastouw I'm trying to do this you described, but no success... Even after altering P100Y to P1Y, the generated tokens are being set to 2116 on the database (and exp to 0).

Is your issue also with Personal Tokens?

I'm thinking how on earth are people not having this issue? I found no reports except mine and another user's. Is it something I did that caused this?

@Jonastouw
Copy link

@gbdematos I just updated my post to include the personal tokens. Have you tried setting those as well?

@gbdematos
Copy link
Author

@Jonastouw it worked now, modifying PassportServiceProvider.php line 84!! Can't believe it, after two days of headache! Thank you so much!

But I'm still curious, is this normal behavior or something I did or my environment maybe? :/

Should I let this Issue open for verification?

@nueko
Copy link

nueko commented Aug 23, 2016

Hmm, is this the Y2038 fx 🔢 ?

@roulendz
Copy link

I did as needed, and OAuth client started to work!
But still
Personal Access Tokens
Does not authorise me :(

Also I can not self consume API :(

@nueko
Copy link

nueko commented Aug 24, 2016

make sure you run
php artisan passport:client --personal,
try add

Passport::tokensExpireIn(Carbon::now()->addDays(15));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));

@ryanhungate
Copy link

I've managed to figure out where the problem is coming from ( or it seems )... I just don't know if this will break anything else. I'm sure this is not recommended but at first glance this is what fixed my problem.

inside the \Laravel\Passport\Guards\TokenGuard :

protected function validCsrf($token, $request)
{
    $compare_token = (string) $request->header('X-CSRF-TOKEN');
    if (empty($compare_token)) {
        $compare_token = (string) $request->header('X-XSRF-TOKEN');
    }
    return isset($token['csrf']) && hash_equals(
        $token['csrf'], $this->encrypter->decrypt($compare_token)
    );
}

@taftse
Copy link

taftse commented Aug 28, 2016

The best way I have found to bypass this issue without changing any files in the vendor folder is by adding the following 2 lines to the boot method of my AuthServiceProvider after Passport::routes();

Passport::tokensExpireIn(Carbon::now()->addYears(20));

Passport::refreshTokensExpireIn(Carbon::now()->addYears(20));

The longest I was able to create a token for was 21 years before I started getting expiry dates starting with a - (minus) which was unable to be validated

Please see https://laravel.com/docs/5.3/passport#configuration for details on the above code

@ryanhungate
Copy link

yeah I had tried something similar where I only added like 30 days, but it still failed when I only had that. I don't know if this is environment related, i'm just using the new Laravel Valet on my mac to test things out. I wonder if I was using Homestead or an Ubuntu box if we get the same results?

@gholol
Copy link

gholol commented Aug 29, 2016

Changing the expiration dates did the trick for me, this needs to be fixed asap. :)

@jampot5000
Copy link

@nueko This is exactly the reason, this happens when using a 32bit version of PHP, the solution is to use the 64bit version of PHP instead.

@gholol
Copy link

gholol commented Aug 30, 2016

@jampot5000 this can't be the reason as I'm currently using 64bit version of PHP 7.1 and I had the same problem.

@erdmenchen
Copy link

erdmenchen commented Sep 2, 2016

Changing the expiration time for private access tokens in the PassportServiceProvider.php
$server->enableGrantType(new PersonalAccessGrant, new DateInterval('P100Y'));
to e.g. P10Y did the trick for me.

Thanks @Jonastouw !

How can this be changed, so that we don't need to change any code in the vendors files?
Maybe a custom Passport::tokensExpireIn for private access tokens is needed?

@gholol
Copy link

gholol commented Sep 2, 2016

@erdmenchen A pull request would be sufficient, as at this stage it's not working out of the box.

@jampot5000
Copy link

jampot5000 commented Sep 2, 2016

@gholol odd as switching to the latest 64bit version of PHP resolved the issue for me, is there another PHP in your path?

at the very least x64 php is required with the default configuration maybe the composer file should be updated or the 100y diff reduced to something before 2038.

@hari03
Copy link

hari03 commented Sep 6, 2016

Doing the changeover from P100Y to P1Y did the trick for me, however, it's was weird to notice auth:api not mentioned in my api middlewaregroup in app\Http\Kernel.php during installation. I had to fix that as well.

If it helps, your 'api' inside 'middlewaregroups' in app\Http\kernel.php should look like:

'api' => [
'throttle:60,1',
 'bindings',
  'auth:api',
  ],

@luiz-brandao
Copy link

It does seem to be the Y2038 problem like @nueko mentioned. On line 25 of \vendor\league\oauth2-server\src\ResponseTypes\BearerTokenResponse.php we have this:

$expireDateTime = $this->accessToken->getExpiryDateTime()->getTimestamp();

In my environment running the 32bit version of PHP, getTimestamp() returns false for dates over 2037.

@haseebeqx
Copy link

i think a better a option is to change new DateInterval('P100Y')) to Passport::tokensExpireIn() and specify Passport::tokensExpireIn(Carbon::now()->addDays(15)); inside boot() in authServiceProvider

@Chathula
Copy link

Chathula commented Oct 4, 2016

it gives another error.. you can't delete the public client token from ui genarated by Vue and Passport.

Console Error

Failed to load resource: the server responded with a status of 500 (Internal Server Error) http://localhost:8000/oauth/personal-access-tokens/fb1173acdafdecdba0d2732025b0cbdb692986982c1900bea70aed73134fdaa75d0fabfebac99091

@chris-rs
Copy link

chris-rs commented Oct 6, 2016

The solution that worked for me was the one proposed by @ryanhungate .
But this solution seems to be totally different from the proposed solutions about the 'expirydates'.

Although the solution from @ryanhungate makes sense, I still don't understand why laravel tokens (with embedded csrf token) successfully validate, since the original code in TokenGuard->validCsrf compares an unencrypted CSRF token (included in decrypted laravel token) against an encrypted CSRF token (in header). I guess this comparison will always fail...

seahken added a commit to seahken/passport that referenced this issue Nov 11, 2016
Changed token expiry from P100Y to P1Y
seahken added a commit to seahken/passport that referenced this issue Nov 11, 2016
Change token expiry from P100Y to P1Y
@themsaid
Copy link
Member

a PR was submitted to solve the issue: #185

@rockers007
Copy link

downloaded latest code which already solved P100Y ,but still I am facing Unauthorized.
check details here dusterio/lumen-passport#17 (comment)

@jnaxo
Copy link

jnaxo commented Oct 5, 2017

My problem : Laravel Passport Personal Token failing Validation.
I had problems with globals scopes.
When i turn them off i solved the problem

@PieterjanDeClippel
Copy link

I forgot to add the auth:api middleware to my routes.
Route::post()->middleware("auth:api")

@tisuchi
Copy link

tisuchi commented Oct 25, 2018

Actually, @hari03 solution works for me.

I just add
'auth:api'
in the app\Http\Kernel.php and it works for me perfectly.

@aonurdemir
Copy link

aonurdemir commented Nov 28, 2018

public function enableGrantType(GrantTypeInterface $grantType, \DateInterval $accessTokenTTL = null)
    {
        if ($accessTokenTTL instanceof \DateInterval === false) {
            $accessTokenTTL = new \DateInterval('PT1H');
        }

        $grantType->setAccessTokenRepository($this->accessTokenRepository);
        $grantType->setClientRepository($this->clientRepository);
        $grantType->setScopeRepository($this->scopeRepository);
        $grantType->setDefaultScope($this->defaultScope);
        $grantType->setPrivateKey($this->privateKey);
        $grantType->setEmitter($this->getEmitter());
        $grantType->setEncryptionKey($this->encryptionKey);

        $this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType;
        $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL;
    }

In above lines of code in AuthorizationServer.php, $accessTokenTTL comes to function from PassportServiceProvider:: registerAuthorizationServer() like

  $server->enableGrantType(
        $this->makePasswordGrant(), Passport::tokensExpireIn()
  );

before AuthServiceProvider::boot() method is called. Hence, Passport::tokensExpireIn(now()->addMinutes(1)); line has no effect on TTLs. As a result, Passport::tokensExpireIn() returns the default value which is 1 year. This is the problem and cannot solve it. Continuing to digging.

@JamieCee20
Copy link

#47 (comment)

This comment issue still seems to exist in 2023.

utsavsomaiya added a commit to utsavsomaiya/passport that referenced this issue Aug 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests