Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

KarolGil's avatar

Laravel Passport - aouth - check when token expires

I use https://laravel.com/docs/6.x/passport

How can I check if the tokien it receives is still active?

0 likes
11 replies
KarolGil's avatar

@nakov

Only as a download, which token belongs to a given user? Because checking requests in this way (in Middleware):

dd($request->user());

The token id is 'accessToken' is 'protected property', and I cannot access it.

Nakov's avatar

@karolgil I don't understand what you are trying to do. If you are making a request using an access token, the route is guarded with the auth:api which then will reject the access with a 403 in case the token is expired. So you don't have to do anything manually to check. If the access is forbidden then you should try and refresh the token, if that one expired as well, you will have to let the user know that a new token is required.

KarolGil's avatar

@nakov

I do not receive a reply from auth:api 403.

  #accessToken: Laravel\Passport\Token {#321
    #table: "oauth_access_tokens"
    #keyType: "string"
    +incrementing: false
    #guarded: []
    #casts: array:2 [
      "scopes" => "array"
      "revoked" => "bool"
    ]
    #dates: array:1 [
      0 => "expires_at"
    ]
    +timestamps: false
    #connection: "mysql"
    #primaryKey: "id"
    #with: []
    #withCount: []
    #perPage: 15
    +exists: true
    +wasRecentlyCreated: false
    #attributes: array:9 [
      "id" => "212ab0b382fd1f2bf530fab2dd717c5fc7f1e2924ee994bd0e1bb83c1a2f3d19b71c1e775d0bc00a"
      "user_id" => 74
      "client_id" => 1
      "name" => "74 token"
      "scopes" => "[]"
      "revoked" => 0
      "created_at" => "2019-12-31 14:03:11"
      "updated_at" => "2019-12-31 14:03:11"
      "expires_at" => "2019-12-31 14:03:11"
    ]

Although the token time has expired, my demand continues.

That's why I wanted to manually check the validity time of the token. Is it possible to do? Or what settings should you have to get the answer auth:api 403?

KarolGil's avatar

@nakov

I check the request using Postman.

If the given token is not present, it receives 403 from auth:api. However, if the token is given, even though it has already expired, the request passes.

Do you have an idea why this can happen?

Nakov's avatar

I don't as I don't have your data to check if what you are saying is true. Plus make sure that the middleware is applied to all the routes.

KarolGil's avatar
KarolGil
OP
Best Answer
Level 9
<?php

namespace App\Http\Middleware;

use App\Models\OauthAccessTokens;
use Closure;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;

class IsActiveToken
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $user = Auth::user();
        $userSerialize = serialize($user);
        $userUnserializeArray = (array) unserialize($userSerialize);

        $arrayKeys = array_keys($userUnserializeArray);
        foreach ($arrayKeys as $value)
        {

            if (strpos($value, 'accessToken') !== false) {

                $userAccessTokenArray = (array) $userUnserializeArray[$value];
                $arrayAccessKeys = array_keys($userAccessTokenArray);
                foreach ($arrayAccessKeys as $arrayAccessValue) {

                    if (strpos($arrayAccessValue, 'original') !== false) {

                        $userTokenId = $userAccessTokenArray[$arrayAccessValue]['id'];
                        $checkToken = OauthAccessTokens::where([
                            ['id', '=', $userTokenId],
                            ['expires_at', '>', Carbon::now()]
                        ])->first();

                        if ( !$checkToken ) {
                            return response()->json([
                                'error'=>true,
                                'msg'=> 'Token time has expired. Please log in again.'
                            ]);
                        }
                    }
                }
            }
        }

        return $next($request);
    }
}

At the moment I have this code.

Does anyone know a better solution?

Nakov's avatar

@karolgil I am really curious on what you are doing, because it does not make sense to do this manually when it is already handled by Passport. Have you checked the documentation completely?

Your middleware is really complex for such a simple check. Make sure that you follow everything in the documentation. Make sure that your config/auth.php for the API uses passport as a driver.. you have this:

'api' => [
    'driver' => 'passport',
    'provider' => 'users',
],

You have this on your route: ->middleware('auth:api').. you are hitting that route for sure?

You've manually created a model OauthAccessTokens, which you don't need :)

1 like
KarolGil's avatar

@nakov

In app/auth.php I have:

        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],

routes/api.php

Route::middleware('auth:api', 'isActiveToken')->group(function () {
    // access routes
});

I used OauthAccessTokens elsewhere.

If it worked everything right away as I wanted, I would not write any additional code.

clemblanco's avatar

TLDR;

Don't expect to "manually invalidate" a token by just changing the expires_at column in the database.

--

I could be wrong but I don't think the expires_at column in the database is used to verify the validity of a JWT token by Passport. I believe this is only there for cross-reference purposes.

When Passport generates a JWT token, it will create it with two attributes:

{
    "accessToken": "someToken",
    "expiresAt": "someDateTime"
}

I think this is the expiresAt on the JWT token that is going to be used.

Looking at how JWT tokens work:

When a server receives a JWT, it can guarantee the data it contains can be trusted because it’s signed by the source. No middleman can modify a JWT once it’s sent.

Which kind of makes sense to me.

Source.

2 likes

Please or to participate in this conversation.