Laravel / React: barryvdh / laravel-cors обрабатывает предварительный запрос HTTP OPTIONS - PullRequest
0 голосов
/ 08 апреля 2019

Просто начинаю с barryvdh/laravel-cors.У меня есть серверное приложение, работающее на порте 8000, которое аутентифицирует пользователей через Laravel Passport, и мое клиентское приложениеact.js, работающее на порте 3000. Сейчас я пытаюсь заставить работать действие «входа в систему».

С клиента, когда я предоставляю правильные учетные данные, токен отправляется обратно, и статус 200. Если учетные данные недействительны, возвращается 401.Так хорошо до сих пор.Однако, если я предоставляю только электронную почту в форме и не пароль, я получаю следующую ошибку, связанную с CORS:

errors

Когда выдается ошибка,происходят следующие сетевые вызовы:

enter image description here

Мой логин на стороне клиента:

login = (email, password) => {
    console.log(email);
    fetch("http://localhost:8000/api/auth/login", {
        method: 'POST',
        body: JSON.stringify({
            'email': email,
            'password': password
        }),
        headers: {
            'Content-Type': 'application/json'
        }
    })
    .then(res => res.json())
    .then(response => {
        console.log(response['access_token']); //with correct credentials this is logged out and set in local storage
        localStorage.setItem('access_token', response['access_token']);
    })
    .catch(error => console.error('Error: ', error));
}

На стороне сервера:

public function login(Request $request)
{
    $request->validate([
        'email' => 'required|string|email',
        'password' => 'required|string',
        'remember_me' => 'boolean'
    ]);

    $credentials = request(['email', 'password']);

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

    $user = $request->user();
    $tokenResult = $user->createToken('Personal Access Token');
    $token = $tokenResult->token;

    if ($request->remember_me) {
        $token->expires_at = Carbon::now()->addWeeks(1);
    }

    $token->save();
    return response()->json([
        'access_token' => $tokenResult->accessToken,
        'token_type' => 'Bearer',
        'expires_at' => Carbon::parse(
            $tokenResult->token->expires_at
        )->toDateTimeString()
    ]);
}

cors.php (опубликовано из пакета barryvdh / laravel-cors):

return [
    'supportsCredentials' => false,
    'allowedOrigins' => ['*'],
    'allowedOriginsPatterns' => [],
    'allowedHeaders' => ['*'],
    'allowedMethods' => ['*'],
    'exposedHeaders' => [],
    'maxAge' => 0,
];

api.php:

Route::group(['prefix' => 'auth',], function () {
    Route::post('login', 'AuthController@login');
    Route::post('register', 'AuthController@register');
    Route::get('register/activate/{token}', 'AuthController@registerActivate');
    Route::group(['middleware' => 'auth:api'], function() {
        Route::get('logout', 'AuthController@logout');
        Route::get('user', 'AuthController@user');
    });
});

Kernel.php:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        \Barryvdh\Cors\HandleCors::class,
        'throttle:60,1',
        'bindings',
    ],
];

protected $middleware = [
    \Barryvdh\Cors\HandleCors::class,
    \App\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    \App\Http\Middleware\TrustProxies::class
];

Посылая тот же POST-запрос (от одного до /api/auth/login без пароля) через почтальона, я получаю ожидаемое сообщение об ошибке:

{
    "message": "The given data was invalid.",
    "errors": {
        "password": [
            "The password field is required."
        ]
    }
}

Но, делая это через клиентское приложение реагировать, ошибка вскриншот брошен.Я предполагаю, что это как-то связано с предварительным запросом HTTP OPTIONS, который браузер отправляет как часть работы CORS.

Как я могу это исправить?Я ожидаю, что 401 будет возвращено для статуса и для реагирующего клиента получит то же самое сообщение JSON, которое Почтальон получает в случае, если пароль пуст.Просто кажется странным, что на основе полезной нагрузки для этого запроса POST возникает ошибка, связанная с CORS.Означает ли это, что сервер и / или клиент неправильно настраивают CORS?

Ответы [ 2 ]

1 голос
/ 16 апреля 2019

Кажется, что ошибка генерируется при возникновении ошибки в вашем бэкэнде.

Как указано в документах :

При возникновении ошибки,промежуточное ПО не работает полностью.Поэтому, когда это произойдет, вы не увидите фактический результат, но вместо этого получите ошибку CORS.

Эта проблема помогла выяснить источник ошибки

1 голос
/ 15 апреля 2019

Прежде всего, член класса:

protected $middleware

Применит промежуточное программное обеспечение для api и web

С laravel.com / docs / 5.8 / middleware # registering-middleware

Если вы хотите, чтобы промежуточное ПО запускалось при каждом HTTP-запросе к вашему приложению, укажите класс промежуточного ПО в спискеСвойство $ middleware вашего приложения / класс Http / Kernel.php.

См. также: barryvdh / laravel-cors # global-use

Попытайтесь зарегистрировать ваше промежуточное ПО один раз, удалив: \Barryvdh\Cors\HandleCors::class вашей 'api' группы промежуточного ПО .

И для логических целей рефакторинг вашего protected $middleware с помощью:

protected $middleware = [
    \App\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    \App\Http\Middleware\TrustProxies::class,
    \Barryvdh\Cors\HandleCors::class,
];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...