Laravel 在所有 api 路由中使用 Web 身份验证重定向到主页

Posted

技术标签:

【中文标题】Laravel 在所有 api 路由中使用 Web 身份验证重定向到主页【英文标题】:Laravel using web authentication in all api routes redirect to home 【发布时间】:2019-02-09 12:33:54 【问题描述】:

我想对所有 api 路由使用 web 身份验证。我创建了中间件,这就是它的样子

Route::group(['middleware' => ['auth:web'], 'prefix' => 'v1',], function ($router) 
   Route::apiResource('subscriptions', 'Api\SubscriptionController');
   Route::post('subscriptions/id/resend', 'Api\SubscriptionController@resend')->name('resend');
   Route::post('subscriptions/id/grace', 'Api\SubscriptionController@addGrace')->name('grace');
   Route::apiResource('accounts', 'Api\SocialMediaAccountController');
   Route::post('accounts/id/reset', 'Api\SocialMediaAccountController@reset');
Route::apiResource('customers', 'Api\CustomerController');
);

当我已经登录并尝试向 api 路由发出请求时,它会将我重定向到主页。我怎样才能解决这个问题 ?

这里是 config/auth.php

 'defaults' => [
    'guard' => 'web',
    'passwords' => 'users',
],
'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],
'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\User::class,
    ],

    // 'users' => [
    //     'driver' => 'database',
    //     'table' => 'users',
    // ],
],

如果我已经登录,我不希望 api 路由被重定向。我只想进行网络授权并继续执行相同的请求。

【问题讨论】:

I don't want api routes to be redirected. I just want to do web authorization and continue with same request. 如果您没有经过身份验证,那么您希望它如何工作? 这是预期的行为。在访问受保护的路由之前,您应该先登录。如果你期待别的东西,也许你不应该使用auth:web中间件。 @Devon 我忘了说当我在网络浏览器中打开 api/v1/subscription 时我已经登录了。它是获取请求,因此它应该列出我所有的订阅,但它会重定向我。 @YohanesGultom 忘了说我已经登录了。 有什么理由不使用 auth:api 中间件来保护 API 路由? 【参考方案1】:

只有两个更新来限制您的 api 路由以要求您的网络身份验证会话发出 api 请求。

    将中间件从 api 更新为 web
# File: app/Providers/RouteServiceProvider.php

protected function mapApiRoutes()
    
        Route::prefix('api')
             ->middleware('web') # <-- CHANGE to 'web'
             ->namespace($this->namespace."\\API")
             ->group(base_path('routes/api.php'));

    
    将中间件从 auth:api 更新为 auth:web(或简称为 auth
# routes/api.php
Route::middleware('auth:web')->get('/user', function (Request $request) 
     return $request->user();
);

【讨论】:

【参考方案2】:

Laravel 中的 web 和 api 路由有很多不同之处。最大的不同是默认包含的中间件。

可以在app/Http/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' => [
        'throttle:60,1',
        'bindings',
    ],

API 应该是无状态的,因此不会设置 cookie 和会话。由于 api 路由不会启动会话,因此您将无法获得经过身份验证的会话。

您可以将您的路线设置为使用“网络”组,或了解如何通过 javascript 使用您自己的 API:https://laravel.com/docs/5.6/passport#consuming-your-api-with-javascript。

【讨论】:

以上是关于Laravel 在所有 api 路由中使用 Web 身份验证重定向到主页的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 路由、api 和 web 用例

在 Laravel 中使用无需身份验证的 api 路由

使用版本控制实现 Laravel API 路由

如何从 Laravel 8 中的自定义 Web 路由中删除“api/”前缀?

Laravel 的路由

在 Laravel 8 中使用 API 路由时返回错误