Markus
Markus

Reputation: 2061

Laravel Passport TokenGuard::__construct() must implement interface

I'm creating a rest api with Laravel and Laravel Passport. I try to access a route protected with the default laravel api auth middleware:

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

Route::prefix('auth')->group(function () {
    Route::post('login', 'Auth\ApiAuthController@login');
});

In the request header I pass Authorization: Bearer <my_secret_token> but I get this exception:

Argument 1 passed to Illuminate\Auth\TokenGuard::__construct() must implement interface Illuminate\Contracts\Auth\UserProvider, null given, called in /Users/markusheinemann/Projekte/Lycus/application/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php on line 162

Here my request header:

{
  content-type: "application/json",
  x-requested-with: "XMLHttpRequest",
  authorization: "********",
  user-agent: "PostmanRuntime/7.13.0",
  accept: "*/*",
  cache-control: "no-cache",
  postman-token: "ebfa3211-958d-4042-ab6a-a488847fc2f7",
  host: "localhost",
  accept-encoding: "gzip, deflate",
  connection: "keep-alive"
}

Here my token creating process:

public function login(LoginRequest $request)
{
    $credentials = $request->only(['email', 'password']);

    if(!Auth::attempt($credentials)) {
        return response()->json(['message' => trans('auth.failed')], 401);
    }

    $token = $request->user()->createToken('Lycus Frontend Client');
    $token->token->save();

    return response()->json([
        'accessToken' => $token->accessToken,
        'expiresAt' => $token->token->expires_at,
    ]);
}

Has anyone an idea why I get this error?

Upvotes: 1

Views: 4175

Answers (1)

Marcus
Marcus

Reputation: 1848

Make sure your user model uses:

class User extends Authenticatable 
{ 
    use HasApiTokens; 
}

---EDIT----

I have seen that login code in some guides on the internet, I personally think it is better to resend the request to the Passport API and let it login and create the tokens.

$request->validate([
    'email'    => 'required|string|email',
    'password' => 'required|string'
]);

$http = new Client();

try {
    $response = $http->post('/oauth/token', [
        'form_params' => [
            'grant_type'    => 'password',
            'client_id'     => 2,
            'client_secret' => 'secret_key_from_passport_client',
            'username'      => $request->email,
            'password'      => $request->password,
        ]
    ]);

    return $response->getBody();
} catch (BadResponseException $e) {
    return response()->json([], 422);
}

---EDIT--- If you move User to other namespace don't forget to change in auth.php

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

    // 'users' => [
    //     'driver' => 'database',
    //     'table' => 'users',
    // ],
],

Upvotes: 1

Related Questions