21

I don't get what I'm doing wrong. I can't set token expiration time.

<?php

namespace App\Providers;

class AuthServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this->registerPolicies();

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

BUT when I call $user->createToken(), for example like this:

<?php
// as a demo
namespace App\Http\Middleware;

class ParseSpecialToken
{
    public function handle($request, Closure $next)
    {
        $user = User::find(1);
        $accessToken = $user->createToken('Some token')->accessToken;
        $request->headers->add(['Authorization' => 'Bearer '. $accessToken]);

        return $next($request);
    }
}

Token expiration is still 1 year, not 1 day. Why? How to change exp time?

Terion
  • 2,396
  • 3
  • 28
  • 42

10 Answers10

37

Here are the methods used to update expiration time for all the grant types :

Personal access token:

public function boot(){
        $this->registerPolicies();

        Passport::routes();
        Passport::personalAccessTokensExpireIn(Carbon::now()->addHours(24));
        Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
}

Rest all

public function boot(){
        $this->registerPolicies();

        Passport::routes();
        Passport::tokensExpireIn(Carbon::now()->addHours(24));
        Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
}

Just update the above code in the boot method of AuthServiceProvider.

vivek takrani
  • 3,858
  • 2
  • 19
  • 33
23

The createToken() method creates a Personal Access Token. By default, these tokens expire after 1 year (or 100 years, if created by laravel/passport <= 1.0.11). The expiration time for this type of token is not modified by the Passport::tokensExpireIn() or Passport::refreshTokensExpireIn() methods.

laravel/passport >= 7.0.4

Passport version 7.0.4 added a new method Passport::personalAccessTokensExpireIn() that allows you to update the expiration time for personal access tokens. If you are on this version or later, you can add this method call to your AuthServiceProvider::boot() method.

Passport::personalAccessTokensExpireIn(Carbon::now()->addDays(1));

laravel/passport < 7.0.4

If you are not yet on passport version 7.0.4, you can still modify the personal access token expiration time, but it is more manual. You will need to enable a new instance of the personal access grant with your desired expiration time. This can also be done in your AuthServiceProvider::boot() method.

// If the server has already been resolved, get it out of the container
// and modify it. Otherwise, use an `afterResolving` callback so that
// it is not being forced to resolve here.
if ($this->app->resolved(\League\OAuth2\Server\AuthorizationServer::class)) {
    $server = $this->app->make(\League\OAuth2\Server\AuthorizationServer::class);
    $server->enableGrantType(new \Laravel\Passport\Bridge\PersonalAccessGrant(), new \DateInterval('P100Y'));
} else {
    $this->app->afterResolving(\League\OAuth2\Server\AuthorizationServer::class, function ($server) {
        $server->enableGrantType(new \Laravel\Passport\Bridge\PersonalAccessGrant(), new \DateInterval('P100Y'));
    });
}

Note

Modifying the expires_at field in the database will not do anything. The real expiration date is stored inside the token itself. Also, attempting to modify the exp claim inside the JWT token will not work, since the token is signed and any modification to it will invalidate it. So, all your existing tokens will have their original expiration times, and there is no way to change that. If needed, you will need to regenerate new tokens.

patricus
  • 59,488
  • 15
  • 143
  • 145
  • Thanks. I can say this is valid answer. I've already check lifetime of token using [JWT.io](https://jwt.io). Just input the token, and look at "exp" variable. Works on Laravel 5.5; lcobucci/jwt 3.3.3; laravel/passport ~4.0 – ibnɘꟻ Nov 16 '21 at 08:56
  • Just add some additional tips. You should check the file oauth public & private key before setting the token lifetime. This will help you when need to generate a new passport key. Here's my snippet code, https://gist.github.com/fendis0709/e86f25bfa4006e20ca6a96eed8df9b4e – ibnɘꟻ Nov 22 '21 at 03:52
  • 1
    @ibnɘꟻ I've updated the `< 7.0.4` code to resolve that issue about the keys. The afterResolving callback will prevent the code from resolving the AuthorizationServer during the composer install, so you won't have that issue. – patricus Jun 27 '23 at 18:39
11

The Passport docs seem to answer this question

https://laravel.com/docs/5.6/passport#token-lifetimes

In the boot method of AuthServiceProvider call Passport::tokenExpiresIn()

public function boot()
{
    $this->registerPolicies();

    Passport::routes();

    Passport::tokensExpireIn(now()->addDays(15));

    Passport::refreshTokensExpireIn(now()->addDays(30));
}
anemo
  • 1,327
  • 1
  • 14
  • 28
1

Use personalAccessTokensExpireIn method in laravel 8

<?php
    
    namespace App\Providers;
    
    use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
    use Illuminate\Support\Facades\Gate;
    use Laravel\Passport\Passport;
    
    class AuthServiceProvider extends ServiceProvider
    {
        /**
         * The policy mappings for the application.
         *
         * @var array
         */
        protected $policies = [
            'App\Models\Model' => 'App\Policies\ModelPolicy',
        ];
    
        /**
         * Register any authentication / authorization services.
         *
         * @return void
         */
        public function boot()
        {
            $this->registerPolicies();
    
            Passport::routes();
            Passport::personalAccessTokensExpireIn(\Carbon\Carbon::now()->addDays(30));
            Passport::refreshTokensExpireIn(\Carbon\Carbon::now()->addDays(15));
        }
    }
0

Ah, figured out the personal tokens are always long-lived and this cannot be configured :(

Terion
  • 2,396
  • 3
  • 28
  • 42
0

Please see this implementation, and here how to replace PassportServiceProvider by your's. It worked for me with Laravel 5.5

vitsen
  • 19
  • 4
0

File: AuthServiceProvider.php

Add these lines

use Laravel\Passport\Bridge\PersonalAccessGrant;
use League\OAuth2\Server\AuthorizationServer;

Add the following code in boot function

public function boot() {
     Passport::routes();
     $lifetime = new \DateInterval('PT24H'); // For 24hours

     $this->app->get(AuthorizationServer::class)->enableGrantType(new PersonalAccessGrant(), $lifetime);
}
GuruAmmu
  • 11
  • 1
  • 1
    Explain why this will solve the issue and also where the user is going wrong – Coder Jul 23 '19 at 15:24
  • Or how it adds any more information than the existing answers to the question. FYI, my answer, more than a month prior, already covered this. – patricus Sep 26 '19 at 01:51
0

I was able to extend the lifetime of the Personal access token by creating a PassportServiceProvider in my project that extends the PassportServiceProvider from the laravel-passport package. Then I just added this method to override the one from the PassportServiceProvider.



    /**
     * Register the authorization server.
     *
     * @return void
     */
    protected function registerAuthorizationServer()
    {
        $this->app->singleton(AuthorizationServer::class, function () {
            return tap($this->makeAuthorizationServer(), function ($server) {
                $server->enableGrantType(
                    $this->makeAuthCodeGrant(), Passport::tokensExpireIn()
                );

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

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

                $server->enableGrantType(
                    new PersonalAccessGrant(), Passport::tokensExpireIn() // this is the line that was updated from the original method
                );

                $server->enableGrantType(
                    new ClientCredentialsGrant(), Passport::tokensExpireIn()
                );

                if (Passport::$implicitGrantEnabled) {
                    $server->enableGrantType(
                        $this->makeImplicitGrant(), Passport::tokensExpireIn()
                    );
                }
            });
        });
    }

Then I just updated the provider in the app.php config file to use the one from my project.

-2

you can do this:

$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
$token->expires_at =
        Carbon::now()->addDays(env('PERSONAL_ACCESS_TOKEN_EXPIRY__DAYS'));

$token->save();
maturecheese
  • 92
  • 1
  • 9
  • 4
    The `expires_at` value in the DB table is just for reference. The expiration timestamp is encoded into the JWT token. This would not work. – Tihomir Mihaylov Feb 01 '18 at 16:54
  • I think the answer is based on the post `https://medium.com/modulr/create-api-authentication-with-passport-of-laravel-5-6-1dc2d400a7f` But its not working – ManojKiran A Feb 03 '19 at 00:59
  • In passport document it says that: `The expires_at columns on Passport's database tables are read-only and for display purposes only. When issuing tokens, Passport stores the expiration information within the signed and encrypted tokens. If you need to invalidate a token you should revoke it.` – kodmanyagha Sep 04 '22 at 20:43
-5

Yes, I just wasted one day to find this problem in VERSION = '5.8'.

For now, maybe we need modify your-project/vendor/laravel/passport/src/Passport.php.

Change this -----> new DateInterval('P1Y') . it is php function Represents a date interval.

D---> means Day Y---> means year M---> means Month

three types of token in passport

1.tokensExpireIn in 303 line.

  1. personalAccessTokensExpireIn in 341 line .

  2. refreshTokensExpireIn in 322 line.

  • 2
    It's not a good idea to modify vendor code. It'll get overwritten with your next composer update, and vendor changes are not recorded in your repo, so they can't be deployed to new environments. My answer shows you how to solve the issue for personal access tokens without modifying your vendor code. – patricus Sep 26 '19 at 02:00