1

Thank you in advance, I want multiple laravel passport guards as my system has 2 user types, 1) Admin, 2) Normal User. for both, I have separate routes and authentication modules(Login, register, logout, etc). so I need a separate passport guard for the API authentication. a few of the codes I added as below

config/auth.php looks like below

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
            'hash' => false,
        ],
        'api-admin' => [
            'driver' => 'passport',
            'provider' => 'admins',
            'hash' => false,  
        ]
    ],

Here i defined 2 guards for admin and user

'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        'admins' => [
            'driver' => 'eloquent',
            'table' => App\Models\Admin::class,
        ],
],

Here i defined 2 providers for admin and user

Now i am creating token like

$tokenResult = $user->createToken('TOKEN_DEMO');        
$token = $tokenResult->token;
$token->save();
$accessToken = $tokenResult->accessToken;

It is generating well as expected for admin user with user_id = 1 (As an example consider user_id = 1) this is about generating token for the admin user

the same way normal user logged in and generating token as same as above then this will also generate the token for the user with user_id = 1 in oauth_clients table

The table looks like as mentioned in the screenshot enter image description here

The concern is that if the normal user logged out then automatically admin user's token will be destroyed as both's user_id is 1 in oauth_clients table while guards is different for both

Please help me out for the same

Ronak Solanki
  • 341
  • 2
  • 5
  • 14

2 Answers2

3

It's also a security issue as your user with same id as admin can pass admin authentication middleware. Following method is the cleanest workaround I've found. You have to use different clients for your guards. You have to run

passport:install

two times if you have two guards using Passport. it will generate two clients. In new versions of Passport(I think after release of Laravel 8) when you are creating a client it asks you for a provider(Defined in auth.providers config). Each provider needs one client. If you are using old versions you can manually assign providers in oauth_clients table. enter image description here Now when generating token you have to specify client id. In older versions you could do this by changing a public property of one of Passport classes but now you should register ClientRepository again.

App::clearResolvedInstance(ClientRepository::class);
app()->singleton(ClientRepository::class, function () {
    return new ClientRepository(User::CLIENT_ID, null); // You should give the client id in the first parameter
});
$token = $user->createToken('TOKEN-EXAMPLE');
$accessToken = $token->accessToken;

Now if you check your access tokens table you can see that client ids are different. Everything is fine now.

You mentioned there might be an issue with revoking tokens but I believe even in your case(using same client and not specifying providers) if you revoke a user token with same id as admin, admin's token will still remain. Revoking user token:

$user = Auth::guard('user-api')->user();
$user->token()->revoke();
Parsa_Gholipour
  • 794
  • 5
  • 16
  • Hello, Thank you so much for your answer, you saved my time, I have implemented your code for the creation of token while regarding revoking token, I have one issue, currently, i am revoking all existing token of a particular user when they log in so all previous session of that user will be destroyed, I am doing that with looping through tokens of the user and then $token->delete() but it is also deleting admin client token too, I want to just delete users client token – Ronak Solanki Nov 30 '20 at 05:09
  • @RonakSolanki Hello, you are welcome. You shouldn't delete all tokens of certain user. As I mentioned at the end of my answer you should only revoke current user's token. $user = Auth::guard('user-api')->user(); $user ->token()->revoke(); Anyways deleting a token is not a good practice. Even if you want to disable a token, use revoke function $token->revoke() – Parsa_Gholipour Nov 30 '20 at 12:03
  • Yes, I know, if i want to revoke all previous tokens of specific users of specific clients, then is it possible? currently, if I revoke the token of users role then it is also revoking admins – Ronak Solanki Nov 30 '20 at 13:23
  • @RonakSolanki Yes. First get tokens of that client. $tokens = \Laravel\Passport\Token::where('client_id', 1)->get(); Then use Foreach and call revoke on each token – Parsa_Gholipour Nov 30 '20 at 13:30
  • 1
    Okay, thanks a lot for your help and time :) – Ronak Solanki Dec 01 '20 at 04:31
  • Hi @Parsa_Gholipour, i have tried this but for some reason it would not change the value of client_id in access tokens table – Nyuu Oct 18 '21 at 19:03
0

does the guard apear anywhere on the token? or do tokens only have scopes? and if so, why would you use guards when you can use scopes... good day!

[Edit]

in my case, im using roles and permissions to write my scopes... roles and permissions are guard based and a permission or role with a admin guard cannot be assigned to a user unless we add the 'admin' key with (in my case) 'passport' drive and 'user' provider...