Laravel / React:Barryvdh / laravel-cors处理飞行前HTTP OPTIONS请求

时间:2019-04-08 00:29:49

标签: php reactjs laravel cors

刚开始使用toms_topic。我有一个运行在端口8000上的服务器端应用程序,该应用程序通过Laravel Passport对用户进行身份验证,而我的react.js客户端应用程序运行在端口3000上。现在,我正在尝试执行“登录”操作。

当我提供正确的凭据时,会从客户端发送回令牌,并且状态为200。当凭据无效时,将返回401。到目前为止很好。但是,如果我仅以电子邮件形式提供电子邮件,而没有提供密码,则会出现以下与CORS相关的错误:

errors

引发错误时,将发生以下网络调用:

enter image description here

我在客户端的登录名:

barryvdh/laravel-cors

服务器端:

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() ]); } (从barryvdh / laravel-cors软件包中发布):

cors.php

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

通过邮递员进行相同的POST请求(一个到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 ]; ,密码除外),我得到了预期的错误消息:

/api/auth/login

但是,通过react client应用程序进行此操作会引发屏幕截图中的错误。我猜想这与浏览器发出的预检HTTP OPTIONS请求有关,这是CORS工作原理的一部分。

我该如何纠正?我希望在密码为空的情况下返回401,以获取状态信息,并让React客户端获得与Postman相同的JSON消息。似乎很奇怪,基于该POST请求的有效负载,会发生CORS相关错误。这是否意味着服务器和/或客户端未正确设置CORS?

2 个答案:

答案 0 :(得分:1)

首先是班级成员:

protected $middleware

将为apiweb都应用中间件

来自 laravel.com/docs/5.8/middleware#registering-middleware

  

如果希望中间件在对应用程序的每个HTTP请求期间运行,请在app / Http / Kernel.php类的$ middleware属性中列出中间件类。

另请参见: barryvdh/laravel-cors#global-usage

因此,尝试通过删除以下内容来一次注册中间件: 您的\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,
];

答案 1 :(得分:1)

当您的后端发生错误时,似乎会抛出该错误。

docs中所述:

  

发生错误时,中间件无法完全运行。所以什么时候   发生这种情况,您将看不到实际结果,但会得到CORS   错误。

issue帮助弄清错误的根源