Laravel Паспорт - проверка функциональности возвращает несанкционированный 401 - PullRequest
1 голос
/ 25 марта 2020

Я пытаюсь проверить конечную точку входа в систему, где в случае успешного ответа, среди прочего, возвращается access_token.

Я использую RefreshDatabase, поэтому я изменил метод входа на контроллере на получить client_secret с помощью вызова DB. Я протестировал dd() и могу подтвердить, что client_secret изменяется при каждом запуске phpunit в терминале. Учетные данные верны, и конечная точка API работает - только не при запуске через тест. Например, у меня настроены таблицы паспортов на моем mysql сервере, и я могу успешно войти в систему при работе с Postman. Только при попытке запустить тест я получаю ошибку 401.

Вот мои AuthTest

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class AuthTest extends TestCase
{
    use RefreshDatabase;



    /**
     * @test
     */
    public function a_user_receives_an_access_token()
    {

         \Artisan::call('passport:install');

        $user = factory('App\User')->create();

        $response = $this->json('POST', '/api/login', [
            'username' => $user->email,
            'password' => 'password'
        ]);



        $response
            ->assertJson([
                'access_token' => true
            ]);


    }
}

маршруты / API. php

Route::post('login', 'AuthController@login');

AuthController@login:

    public function login(Request $request) {
        $http = new \GuzzleHttp\Client;

        try {
            $response = $http->post(config('services.passport.login_endpoint'), [
                'form_params' => [
                    'grant_type' => 'password',
                    'client_id' =>  '2', //config('services.passport.client_id')
                    'client_secret' => DB::table('oauth_clients')->where('id', 2)->pluck('secret')[0], //config('services.passport.client_secret'),
                    'username' => $request->username,
                    'password' => $request->password
                ]
            ]);

            return $response->getBody();

        } catch (\GuzzleHttp\Exception\BadResponseException $e) {



            if ($e->getCode() == 400 || $e->getCode() == 401) {
                return response()
                ->json([
                    'status' => $e->getCode(),
                    'message' => 'Your email and/or password are incorrect',
                    'expanded' => $e->getMessage()
                ]);
            }

            return response()
                ->json([
                    'status' => $e->getCode(),
                    'message' => $e->getMessage()
                ]);
        }

    }

Я посмотрел на этот вопрос и принял ответ: Как проверить аутентификацию через API с Laravel Паспортом?

Я не могу использовать следующее

public function setUp() {
    parent::setUp();
    \Artisan::call('migrate',['-vvv' => true]);
    \Artisan::call('passport:install',['-vvv' => true]);
    \Artisan::call('db:seed',['-vvv' => true]);
}

Это приводит к ошибке:

PHP Fatal error: Declaration of Tests\Feature\AuthTest::setUp() must be compatible with Illuminate\Foundation\Testing\TestCase::setUp()

Редактировать: я только что добавил

    public function setUp() :void {
        parent::setUp();
        \Artisan::call('migrate',['-vvv' => true]);
        \Artisan::call('passport:install',['-vvv' => true]);
        \Artisan::call('db:seed',['-vvv' => true]);
    }

, но проблема все еще сохраняется

Редактируйте снова:

Если я проверю маршрут oauth напрямую, он проходит .

    public function testOauthLogin() {
        $oauth_client_id = 2;
        $oauth_client = OAuthClient::findOrFail($oauth_client_id);

        $user = factory('App\User')->create();

        $body = [
            'username' => $user->email,
            'password' => 'password',
            'client_id' => $oauth_client_id,
            'client_secret' => $oauth_client->secret,
            'grant_type' => 'password',
            'scope' => '*'
        ];
        $this->json('POST','/oauth/token',$body,['Accept' => 'application/json'])
            ->assertStatus(200)
            ->assertJsonStructure(['token_type','expires_in','access_token','refresh_token']);
    }

Но моя пользовательская конечная точка, которая использует жрет, терпит неудачу. Я не знаю, почему

Отредактируйте снова:

Я думаю, что проблема с Guzzle, но я не уверен. Я нашел другую реализацию того, что я пытаюсь сделать, а именно:

 public function login(Request $request) {
        $request->request->add([
            'username' => $request->username,
            'password' => $request->password,
            'grant_type' => 'password',
            'client_id' => $this->client->id,
            'client_secret' => $this->client->secret,
            'scope' => '*'
        ]);

        $response = Route::dispatch(Request::create(
            'oauth/token',
            'POST'
        ));


    }

Выше работает.

...