I\'m trying to test the authentication with Laravel\'s Passport and there\'s no way... always received a 401 of that client is invalid, I\'ll leave you what I\'ve tried:
I wasn't familiar with the Passport tool that Dwight is referring to when I wrote this, so it's possible that's a simpler solution. But here's something that may help. It produces a token for you, that you can then apply to your mock-API call.
/**
* @param Authenticatable $model
* @param array $scope
* @param bool $personalAccessToken
* @return mixed
*/
public function makeOauthLoginToken(Authenticatable $model = null, array $scope = ['*'], $personalAccessToken = true)
{
$tokenName = $clientName = 'testing';
Artisan::call('passport:client', ['--personal' => true, '--name' => $clientName]);
if (!$personalAccessToken) {
$clientId = app(Client::class)->where('name', $clientName)->first(['id'])->id;
Passport::$personalAccessClient = $clientId;
}
$userId = $model->getKey();
return app(PersonalAccessTokenFactory::class)->make($userId, $tokenName, $scope)->accessToken;
}
Then you an just apply it to the headers:
$user = app(User::class)->first($testUserId);
$token = $this->makeOauthLoginToken($user);
$headers = ['authorization' => "Bearer $token"];
$server = $this->transformHeadersToServerVars($headers);
$body = $cookies = $files = [];
$response = $this->call($method, $uri, $body, $cookies, $files, $server);
$content = $response->getContent();
$code = $response->getStatusCode();
If you need to be able to parse the token, try this:
/**
* @param string $token
* @param Authenticatable $model
* @return Authenticatable|null
*/
public function parsePassportToken($token, Authenticatable $model = null)
{
if (!$model) {
$provider = config('auth.guards.passport.provider');
$model = config("auth.providers.$provider.model");
$model = app($model);
}
//Passport's token parsing is looking to a bearer token using a protected method. So a dummy-request is needed.
$request = app(Request::class);
$request->headers->add(['authorization' => "Bearer $token"]);
//Laravel\Passport\Guards\TokenGuard::authenticateViaBearerToken() expects the user table to leverage the
//HasApiTokens trait. If that's missing, a query macro can satisfy its expectation for this method.
if (!method_exists($model, 'withAccessToken')) {
Builder::macro('withAccessToken', function ($accessToken) use ($model) {
$model->accessToken = $accessToken;
return $this;
});
/** @var TokenGuard $guard */
$guard = Auth::guard('passport');
return $guard->user($request)->getModel();
}
/** @var TokenGuard $guard */
$guard = Auth::guard('passport');
return $guard->user($request);
}