66

After setup of passport, I have configured and created a controller to manage Register-Login- and - access to a resource for a general external post request. I do not need for a specific client. But when I try to create a token in the registration or in the login:

$tokenObj=$user->createToken('APPLICATION')->accessToken;

The error is:

RuntimeException: Personal access client not found. Please create one. in file C:\xampp7.1\htdocs\passport\vendor\laravel\passport\src\ClientRepository.php on line 94 Stack trace: 1. RuntimeException->() C:\xampp7.1\htdocs\passport\vendor\laravel\passport\src\ClientRepository.php:94 2. Laravel\Passport\ClientRepository->personalAccessClient() C:\xampp7.1\htdocs\passport\vendor\laravel\passport\src\PersonalAccessTokenFactory.php:71

How can I solve it?

Jonio
  • 1,213
  • 2
  • 15
  • 35

8 Answers8

150

for me it solved by running

php artisan passport:install

because it have been happened after refreshing my database.

Ruberandinda Patience
  • 3,435
  • 3
  • 20
  • 18
44

In addition to the namelivia's comment. As Laravel doc says:

Before your application can issue personal access tokens, you will need to create a personal access client. You may do this using the passport:client command with the --personal option. If you have already run the passport:install command, you do not need to run this command:

php artisan passport:client --personal

But if you did not run the command:

php artisan passport:install

You should run it first.

mwa91
  • 3,949
  • 1
  • 13
  • 10
Ruslan Skaldin
  • 981
  • 16
  • 29
40

You have to create access clients first. It is documented here. An access client it not the same than a user token, you can have one access client and many users with different passwords and tokens.

namelivia
  • 2,657
  • 1
  • 21
  • 24
14

After running the command

php artisan passport:client --personal

and give you this prompt

 What should we name the personal access client? [Artisan Personal Access Client]:

don't worry just type in any name and press the enter key.

stanley mbote
  • 956
  • 1
  • 7
  • 17
8

should I call

php artisan passport:install

every time I run

php artisan:migrate

there is a way to do it properly?

JahStation
  • 893
  • 3
  • 15
  • 35
6

Simply run this command

php artisan passport:install --force
5

The Traits

There're sometimes confusions with the Traits for the User Model.

Sanctum and Passport came with the same Trait, called HasApiToken.

You may require to change the namespace in the user model from:

from

use Laravel\Sanctum\HasApiTokens;

to

use Laravel\Passport\HasApiTokens;

Testing with PAC

When implementing unit test, you may create a test to create a personal-access-client too:

In case you hash your secrets in your database, you should set Passport::$hashesClientSecrets to false in your test-cases if you need the unhashed password

use RefreshDatabase

/** @test */
public function can_create_a_personal_access_client()
{
    Passport::$hashesClientSecrets = false;

    $this->artisan(
        'passport:client', 
        ['--name' => config('app.name'), '--personal' => null]
    )->assertSuccessful();


    $this->assertDatabaseCount(PersonalAccessClient::class,1);
}

Because we use the RefreshDatabase trait, it's usefull to create a helper trait for other tests that may require a personal-access-client:

<?php

namespace Tests;

use App\Models\User;
use Illuminate\Testing\TestResponse;

trait Helper
{
    protected function createPersonalClient()
    {
        Passport::$hashesClientSecrets = false;

        $this->artisan(
            'passport:client',
            ['--name' => config('app.name'), '--personal' => null]
        );

        // use the query builder instead of the model, to retrieve the client secret
        return DB::table('oauth_clients')
            ->where('personal_access_client','=',true)
            ->first();
    }
}

Now, you can re-use the class for other PAT-Tests:

use RefreshDatabase, Helper;

/** @test */
public function can_issue_a_personal_access_token()
{
    $this->createPersonalClient();

    $user = User::factory()->create()->createToken('test');
    
    $this->assertInstanceOf(PersonalAccessTokenResult::class, $user);

    $this->assertObjectHasAttribute('accessToken', $user);
    
    $this->assertObjectHasAttribute('token', $user);
}
lordisp
  • 634
  • 9
  • 21
  • Thank you for the comment! So little guides for laravel with appropriate test suites. It seems very few people do use TDD for laravel, what a shame. Also you should add use Laravel\Passport\Passport; use Illuminate\Support\Facades\DB; in your Helper file to make it work. – Riki_tiki_tavi Jul 15 '23 at 18:11
3

i had the same error over and over again but i didn't how to reproduce it, but i figured it out why. when you execute php artisan passport:install, it stores the two clients IDs in the database after the migrate command, but if you fresh migrate again, it's obvious you'll lose those two previous IDs, this is why this error was shown after executing the install command.

UPDATE php artisan passport:install -f will force recreating the IDs for the new migrated database.