如何使用带有PKCE的授权码授予通过Laravel Passport认证用户(使用密码)?

时间:2020-06-22 20:04:02

标签: php laravel oauth-2.0 access-token laravel-7

对于我的PHP API(将由同一网站上的VueJS使用),我正在尝试使用OAuth 2.0验证用户名和密码,该用户名和密码存储在(MySQL 5.7)数据库中存储的users表中

我正在使用Laravel Passport(确切地说是在Laravel 7.8.1上),并且正在尽最大努力理解文档(我还阅读了链接的常规OAuth文档)并编写一些代码来获取适当的令牌身份验证。

就我而言,至少在我看来,密码授予令牌隐式授予令牌不被使用(或者看起来不再建议使用它们了) (经过几次搜索和一些令人困惑的时刻后,我收集了这些信息)我正在尝试将推荐的授权代码授予与PKCE一起使用

https://laravel.com/docs/7.x/passport#code-grant-pkce

我在这里阅读了文档: https://laravel.com/docs/7.x/passport

可能不是重点,但我在routes/web.php中有这些路由(因为我在使用routes/api.php时遇到会话错误,因此我推迟了一段时间,尽管显然与存在于web而非api路由中的中间件有关。

要回到我当前遇到的问题:例如,我尚不完全清楚文档中使用的示例中没有传达用户名和密码。

当我手动使用https://my.example.com/auth URL时,我确实被重定向到登录表单(使用LoginController中的内置Http\Auth\LoginController.php),所以我尝试传递用户名和密码,但是似乎不起作用。

在将Auth::attempt参数设置为/oauth/authorize的情况下重定向到remember之前,正在使用true。我也尝试过Auth::once,因为它写在文档中非常适合API使用,尽管在这种情况下似乎不适合。

我也对一些事情进行了硬编码,如您所见。我已经通过php artisan passport:client --public创建了一个Passport客户端,其id本身为1,并且现在,对于文档中描述的id为1的用户,也是如此。 / p>

有人对如何使以下路由协同工作以针对数据库实际验证用户名和密码并返回令牌有任何指示吗?将Auth::attempt参数设置为true的remember,但这是正确的方法吗?

Route::get('auth', function (Request $request) {
    $request->session()->put('state', $state = Str::random(40));
    $request->session()->put('code_verifier', $code_verifier = Str::random(128));
    $codeChallenge = strtr(rtrim(
        base64_encode(hash('sha256', $code_verifier, true))
        , '='), '+/', '-_');
    $query = http_build_query([
        'name' => $request->name,
        'password' => $request->password,
        'client_id' => 1,
        'redirect_uri' => 'https://my.example.com/auth/callback',
        'response_type' => 'code',
        'scope' => '',
        'state' => $state,
        'code_challenge' => $codeChallenge,
        'code_challenge_method' => 'S256',
    ]);

    return redirect('https://my.example.com/oauth/authorize?' . $query);
});

Route::get('auth/callback', function (Request $request) {
    $state = $request->session()->pull('state');
    $codeVerifier = $request->session()->pull('code_verifier');
    throw_unless(
        strlen($state) > 0 && $state === $request->state,
        InvalidArgumentException::class
    );
    $response = (new GuzzleHttp\Client)->post('https://my.example.com/oauth/token', [
        'form_params' => [
            'grant_type' => 'authorization_code',
            'client_id' => 1,
            'redirect_uri' => 'https://my.example.com/auth/callback',
            'code_verifier' => $codeVerifier,
            'code' => $request->code,
        ],
    ]);

    return json_decode((string) $response->getBody(), true);
});

0 个答案:

没有答案