第 3 方应用程序的护照授权 - 从前端应用程序使用基于令牌的用户访问 /oauth/authorize

问题描述 投票:0回答:1

我有一个网站,有单独的 fornt(vue)和后端(laravel)应用程序

我使用护照进行身份验证,为用户生成个人访问令牌并将其存储在前端应用程序中,并使用

Bearer authToken
从前端应用程序向后端发送请求以获取受保护的路由

我有一个个人客户来生成这些代币

现在我试图授权其他网站用户访问他们在我的网站中的信息,所以我为第 3 方应用程序创建了一个新的护照客户端

并请求使用该客户端的第三个应用程序的授权

     $query = http_build_query([
        'client_id' => config('mywebsite.auth_client_id'),
        'redirect_uri' => route('thisapp.callback'),
        'response_type' => 'code',
        'scope' => '',
        'state' => Str::uuid()->toString() ,
    ]);
    
    return ['url' => config('mywebsite.mywebsite_url') .'/oauth/authorize?'.$query];

生成授权网址

http://api.mywebsite.com/oauth/authorize?....

问题是这将生成一个后端路由,该路由受 auth:web 保护

用户需要直接登录我的后端,这意味着我需要一个前端应用程序来登录我的后端应用程序

我尝试通过我的前端应用程序使用用户令牌调用此路由,但显然此路由受到网络/会话防护的保护,并且无法识别我的前端令牌

我尝试将 config/passport 中的守卫更改为 api,以便路由与令牌/api 守卫一起使用,但我收到此错误

“留言”: “Laravel\Passport\Http\Controllers\AuthorizationController::__construct(): 参数 #2 ($guard) 必须是类型 照亮\合同\身份验证\StatefulGuard, Laravel\Passport\Guards\TokenGuard 给出”,

我尝试使用 auth:api 中间件覆盖路由

Route::get('/oauth/authorize', [\Laravel\Passport\Http\Controllers\AuthorizationController::class, 'authorize'])->middleware('auth:api');

但当我使用我的身份验证令牌调用路由时仍然要求登录

有没有办法从前端使用 api/token 登录用户而不是后端的 web/session 来调用这些路由?

php laravel laravel-passport laravel-11
1个回答
0
投票

您遇到的错误表明 Laravel Passport 中

AuthorizationController
类的构造函数中存在类型不匹配。具体来说,第二个参数 (
$guard
) 预计为
Illuminate\Contracts\Auth\StatefulGuard
类型,但传递的是
Laravel\Passport\Guards\TokenGuard

这种情况通常会发生,因为

TokenGuard
用于 API 身份验证,而
StatefulGuard
用于基于会话的身份验证,这在 Web 身份验证中很常见。

要解决此问题,您需要确保注入正确的保护类型。以下是排查和修复此问题的分步方法:

第 1 步:检查控制器构造函数

打开

AuthorizationController
类并检查构造函数以了解它需要哪些依赖项。

use Illuminate\Contracts\Auth\StatefulGuard;

public function __construct(StatefulGuard $guard, /* other dependencies */) {
    $this->guard = $guard;
    // other initializations
}

第2步:在Auth Service Provider中配置Guard

确保配置正确的防护并将其传递到控制器。在大多数情况下,您将在

AuthServiceProvider
或服务容器绑定中定义它。

第 3 步:在服务容器中定义正确的守卫

您可能需要将

StatefulGuard
绑定到适当的守卫实现。这可以在
AppServiceProvider
或类似的服务提供商中完成。

use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Support\Facades\Auth;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind(StatefulGuard::class, function ($app) {
            return Auth::guard('web'); // or the appropriate guard
        });
    }

    public function boot()
    {
        //
    }
}

第 4 步:确保
config/auth.php

中的 Guard 配置

确保您的

config/auth.php
文件配置了正确的防护:

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

    'api' => [
        'driver' => 'passport', // or 'token' if you are using Laravel Passport
        'provider' => 'users',
    ],
],

第 5 步:在路由和中间件中使用正确的防护

定义使用

AuthorizationController
的路由或中间件时,确保它们使用正确的防护。例如,Web 路由应使用
web
防护,而 API 路由应使用
api
防护。

中间件使用示例

如果您使用中间件,请确保它引用正确的防护:

Route::middleware(['auth:web'])->group(function () {
    // Define routes that require the web guard
});

通过执行这些步骤,您应该能够确保将正确类型的防护注入到

AuthorizationController
中,解决类型不匹配问题。

如果问题仍然存在,请确保您拥有最新版本的 Laravel Passport 和 Laravel,因为可能有与此问题相关的更新或修复。

© www.soinside.com 2019 - 2024. All rights reserved.