Laravel 10:如何禁用 API 的会话和 CSRF cookies?

huangapple go评论51阅读模式
英文:

Laravel 10: how to disable session and csrf cookies for the api?

问题

我想要禁用我的Laravel应用程序中的所有Cookie。我已经在Web路由上做到了这一点,它运行良好,但我遇到了一个问题,当我在浏览器上使用我的API时,我仍然收到Cookie(Laravel会话和CSRF)。奇怪的是,只有在生产服务器上我才收到set_cookie头部。如果我在我的笔记本上提供应用程序,我就不会收到任何Cookie。我已经检查了.env文件,它们都具有相同的值,只有数据库连接不同。

在app/Http/Kernel.php文件中:

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\View\Middleware\ShareErrorsFromSession::class,
            // \App\Http\Middleware\VerifyCsrfToken::class,
            // \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    /**
     * The application's middleware aliases.
     *
     * Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
     *
     * @var array<string, class-string|string>
     */
    protected $middlewareAliases = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::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' => \App\Http\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];
}

在routes/api.php文件中:

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return ['username' => $request->user()->name];
});

Route::post('login', function (Request $request) {
    Log::debug('test');
    $post = $request->all();
    if (Auth::attempt(['name' => $post['username'], 'password' => $post['password']])) {
        return ['token' => $request->user()->createToken('api')->plainTextToken];
    }
    sleep(1);
    return response(["message" => "invalid credentials"], 401);
});

Route::middleware('auth:sanctum')->post('logout', function (Request $request) {
    $request->user()->currentAccessToken()->delete();
    return [
        'message' => 'logout completed'
    ];
});

Route::middleware('auth:sanctum')->patch('patch-index/texts/{category}', [TextController::class, 'patchIndexes']);
Route::middleware('auth:sanctum')->patch('patch-index/offers/{category}', [OfferController::class, 'patchIndexes']);

Route::middleware('auth:sanctum')->apiResource('texts', TextController::class);

Route::middleware('auth:sanctum')->apiResource('offers', OfferController::class);

Route::middleware('auth:sanctum')->get('categories/{category}', [CategoryController::class, 'show']);

我已经尝试了其他类似问题的解决方案,但没有任何作用。

例如:

  • 我禁用了Kernel.php中的中间件。
  • 我将SESSION_DRIVER更改为array。
  • 在VerifyCsrfToken.php中,我排除了所有路由。

编辑,问题已解决
问题在于EnsureFrontendRequestsAreStateful中间件,我禁用了它,现在一切正常。

英文:

I want to disable all cookies for my laravel application. I already did this for the webroutes and it works fine, but I have the problem, that I still receive cookies (laravel session and csrf), if I use my api on the browser. The weird thing is, that I only get the set_cookie Header on the production server. If I serve the application on my laptop, i don't get any cookies. I already checked the .env file, they have both the same values, only the database connection is different.

app/Http/Kernel.php

class Kernel extends HttpKernel
{
/**
* The application&#39;s global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array&lt;int, class-string|string&gt;
*/
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&#39;s route middleware groups.
*
* @var array&lt;string, array&lt;int, class-string|string&gt;&gt;
*/
protected $middlewareGroups = [
&#39;web&#39; =&gt; [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
//\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\View\Middleware\ShareErrorsFromSession::class,
// \App\Http\Middleware\VerifyCsrfToken::class,
// \Illuminate\Routing\Middleware\SubstituteBindings::class,
],
&#39;api&#39; =&gt; [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class.&#39;:api&#39;,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application&#39;s middleware aliases.
*
* Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
*
* @var array&lt;string, class-string|string&gt;
*/
protected $middlewareAliases = [
&#39;auth&#39; =&gt; \App\Http\Middleware\Authenticate::class,
&#39;auth.basic&#39; =&gt; \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
&#39;auth.session&#39; =&gt; \Illuminate\Session\Middleware\AuthenticateSession::class,
&#39;cache.headers&#39; =&gt; \Illuminate\Http\Middleware\SetCacheHeaders::class,
&#39;can&#39; =&gt; \Illuminate\Auth\Middleware\Authorize::class,
&#39;guest&#39; =&gt; \App\Http\Middleware\RedirectIfAuthenticated::class,
&#39;password.confirm&#39; =&gt; \Illuminate\Auth\Middleware\RequirePassword::class,
&#39;signed&#39; =&gt; \App\Http\Middleware\ValidateSignature::class,
&#39;throttle&#39; =&gt; \Illuminate\Routing\Middleware\ThrottleRequests::class,
&#39;verified&#39; =&gt; \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}

routes/api.php

Route::middleware(&#39;auth:sanctum&#39;)-&gt;get(&#39;/user&#39;, function (Request $request) {
return [&#39;username&#39; =&gt; $request-&gt;user()-&gt;name];
});
Route::post(&#39;login&#39;, function (Request $request) {
Log::debug(&#39;test&#39;);
$post = $request-&gt;all();
if (Auth::attempt([&#39;name&#39; =&gt; $post[&#39;username&#39;], &#39;password&#39; =&gt; $post[&#39;password&#39;]])) {
return [&#39;token&#39; =&gt; $request-&gt;user()-&gt;createToken(&#39;api&#39;)-&gt;plainTextToken];
}
sleep(1);
return response([&quot;message&quot; =&gt; &quot;invalid credentials&quot;], 401);
});
Route::middleware(&#39;auth:sanctum&#39;)-&gt;post(&#39;logout&#39;, function (Request $request) {
$request-&gt;user()-&gt;currentAccessToken()-&gt;delete();
return [
&#39;message&#39; =&gt; &#39;logout completed&#39;
];
});
Route::middleware(&#39;auth:sanctum&#39;)-&gt;patch(&#39;patch-index/texts/{category}&#39;, [TextController::class, &#39;patchIndexes&#39;]);
Route::middleware(&#39;auth:sanctum&#39;)-&gt;patch(&#39;patch-index/offers/{category}&#39;, [OfferController::class, &#39;patchIndexes&#39;]);
Route::middleware(&#39;auth:sanctum&#39;)-&gt;apiResource(&#39;texts&#39;, TextController::class);
Route::middleware(&#39;auth:sanctum&#39;)-&gt;apiResource(&#39;offers&#39;, OfferController::class);
Route::middleware(&#39;auth:sanctum&#39;)-&gt;get(&#39;categories/{category}&#39;, [CategoryController::class, &#39;show&#39;]);

I already tried the solutions on other similar problems, but nothing works.

for example:

I disabled the middleware on the Kernel.php

I changed the SESSION_DRIVER to array

In the VerifyCsrfToken.php i excepted all routes

EDIT, SOLVED IT
The Problem is the EnsureFrontendRequestsAreStateful middleware, i disabled it and now it works fine.

答案1

得分: 1

在检查此部分的Sanctum文档后

如果您计划使用Sanctum对SPA进行身份验证,则应将Sanctum的中间件添加到应用程序的app/Http/Kernel.php文件中的api中间件组中:

&#39;api&#39; =&gt; [
   \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    \Illuminate\Routing\Middleware\ThrottleRequests::class.&#39;:api&#39;,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

所以您只需删除此中间件EnsureFrontendRequestsAreStateful

英文:

After checking the documentation of Sanctum in this part

> if you plan to utilize Sanctum to authenticate a SPA, you should add Sanctum's middleware to your api middleware group within your application's app/Http/Kernel.php file:

&#39;api&#39; =&gt; [
   \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    \Illuminate\Routing\Middleware\ThrottleRequests::class.&#39;:api&#39;,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

So all you need is to remove this middleware EnsureFrontendRequestsAreStateful

huangapple
  • 本文由 发表于 2023年6月16日 05:41:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76485701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定