![](/img/trans.png)
[英]Why does the Laravel API return a 419 status code on POST and PUT methods?
[英]HTTP status code 419 when accessing Laravel api by browser
我無法通過瀏覽器(腳本/控制台/開發工具)在本地主機訪問我的 laravel api 發布路由。 我總是收到 HTTP 419(頁面已過期)狀態錯誤。 有趣的是,我可以通過 postman 成功訪問 api。
路由在每個“auth:sanctum”組之外,所以這不應該是失敗的原因。 因此,我也認為會話和 session 配置不可能是原因,是嗎?
// routes/api.php
Route::post('/test', function() {
return "Hello World @ POST";
}); // => HTTP 419
Route::get('/test', function() {
return "Hello World @ GET";
}); // => HTTP 200
我從 xsrf-checks 中排除了路徑,以排除此錯誤原因:
// VerifyCsrfToken.php
protected $except = [
'api/test',
];
我在 firefox 控制台運行的腳本:
await fetch("http://localhost:8000/api/test", {
"method": "POST"
});
HTTP 請求 firefox 發送到本地主機:
POST /api/test HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0
Accept: */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1:8000/
Origin: http://127.0.0.1:8000
Connection: keep-alive
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Content-Length: 0
我該怎么做才能讓我的 api 在瀏覽器中運行?
編輯#1
應用程序/http/kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array<int, class-string|string>
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array<string, array<int, class-string|string>>
*/
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' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array<string, class-string|string>
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}
原因是App\Http\Middleware\VerifyCsrfToken
which parent class is the Illuminate\Foundation\Http\Middleware\VerifyCsrfToken
在它的 handle 方法中有這段代碼:
public function handle($request, Closure $next)
{
if (
$this->isReading($request) ||
$this->runningUnitTests() ||
$this->inExceptArray($request) ||
$this->tokensMatch($request)
) {
return tap($next($request), function ($response) use ($request) {
if ($this->shouldAddXsrfTokenCookie()) {
$this->addCookieToResponse($request, $response);
}
});
}
throw new TokenMismatchException('CSRF token mismatch.');
}
這個大if
的第一個檢查是$this->isReading($request)
。 該方法負責檢查您正在使用的請求方法,如果您看到它的實現:
/**
* Determine if the HTTP request uses a ‘read’ verb.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function isReading($request)
{
return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']);
}
所以我想不需要更多的話了。
在這里您應該問自己為什么他們遺漏了POST
方法。
如果您對此太確定,可以在App\Http\Middleware\VerifyCsrfToken
覆蓋該方法
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array<int, string>
*/
protected $except = [
//
];
protected function isReading($request): bool
{
return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS', 'POST']);
}
}
你可以開始閱讀這個
post
路由將不起作用。 除非你通過表格來做<form action="/api/test" method="POST">
<button type="submit">Submit</button>
</form>
換句話說,從我所看到的你應該能夠訪問:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.