【问题标题】:Laravel Passport: CreateFreshApiToken in App: Authorization FailedLaravel Passport:应用程序中的 CreateFreshApiToken:授权失败
【发布时间】:2019-05-19 10:24:29
【问题描述】:

我正在尝试使用 PHP 7.2.13Laravel 5.7.18 上安装 Laravel Passport

我的应用程序使用 JavaScript(带有 Vue 的 Axios)在其内部使用 API

我在 JavaScript Web 应用程序中收到 401 Unauthorized 错误。我已经 read the documentation 并将 CreateFreshApiToken 添加到网络内核。 laravel_token cookie 实际上是在设置自己。但是,数据库中的 oauth 表是干净的。

Http/内核

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,
            \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

JavaScript

axios.get("api/users/" + id).then(({ data }) => {
    this.user = data;
});

Auth.php

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

        'api' => [
            'driver'   => 'passport',
            'provider' => 'users',
        ],
    ],

路由(Api.php)

Route::middleware('auth:api')->group(function () {
    Route::resource('users', 'UserController');
    Route::resource('groups', 'GroupController');
    // .. plus more resources
});

Axios 配置:

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

var token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
  window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
  console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

浏览器中返回 401 的标题:

邮递员的工作要求:

【问题讨论】:

    标签: laravel laravel-5 oauth-2.0 axios laravel-passport


    【解决方案1】:

    如果您使用用户名和密码进行初始登录,那么假设您正在构建一个有权进行用户/密码登录尝试的第一方应用程序。

    如果您正在构建一个反应式应用程序,强烈建议您使用 Angular、React.js 或 Vue.js,然后是 SPA(单页应用程序) 方法将产生更强大的产品。

    https://en.wikipedia.org/wiki/Single-page_application


    您应该注意,使用这种特殊方法,如果您的应用程序 发出静态(无 ajax 请求)并因此在浏览器中重新加载, 您将丢失身份验证令牌。在这种情况下,您不是在玩主持人 对于一个定义为 SPA 的应用程序,因此如果您需要在 静态请求重新加载,然后您需要将令牌存储在 cookie 中,我 建议使用 cookie 而不是 localStorage,因为 localStorage 不能 100% 保证在所有网络浏览器中都可供您使用。

    如果您的应用在同一个域中,则无需使用 护照。相反,本机会话 cookie 身份验证非常好,所有 你必须做的是确保你传递 CSRF 令牌以进行发布 请求。


    对于用户/通行证令牌授予,您应该遵循以下准则: https://laravel.com/docs/5.7/passport#password-grant-tokens

    根据该指南,当您向/oauth/token 发出成功请求时,应在您的应用程序中将返回的令牌设置为带有不记名令牌的Authorization 标头。

    令牌请求响应如下所示:

    {
        "token_type": "Bearer",
        "expires_in": 31536000,
        "access_token": "eyJ0eXAiOiJKVJhb...nheKL-fuTlM",
        "refresh_token": "def502008d6313e...94508f1cb"
    }
    

    您应该按如下方式请求和处理该 JSON 对象:

    axios.post('/oauth/token', {
        grant_type: "password",
        client_id: "1",
        client_secret: "zkI40Y.......KvPNH8",
        username:"email@address.com",
        password:"my-password"
    }).then( response => {
    
        axios.defaults.headers.common['Authorization'] = `Bearer ${response.data.access_token}` 
    
    } );
    

    client_id (id) 和 client_secret 的值来自 oauth_clients 表,其中应该已经有一个条目。

    如果没有,则运行php artisan passport:client --password

    不要忘记您必须配置一些标头,请查看这篇文章,其中包含 Oauth Authorization 标头的一些相关信息: How to send authorization header with axios

    【讨论】:

    • 您好,感谢您的建议,但我已经仔细检查了授权标头,并且所有内容都与文档相符。
    • 您能否在原始帖子中粘贴登录时响应标头的副本以及登录后请求的请求标头?
    • 是的,我用两张截图更新了我的问题。一个来自浏览器(返回 401)和一个来自 Postman(工作)
    • 您是否在关注第一方应用程序的教程? laravel.com/docs/5.7/passport#password-grant-tokens
    • 我用一个处理 oauth 令牌请求的小例子更新了我的答案。
    【解决方案2】:

    如果您说您的表在数据库中是干净的,请尝试再次运行此命令:

    php artisan passport:install
    

    此命令将创建生成安全访问令牌所需的加密密钥。此外,该命令将创建“个人访问”和“密码授予”客户端,用于生成访问令牌:

    Laravel 5.7 Passport docs

    【讨论】:

    • 不,只是添加更多访问令牌。 php artisan passport:install Encryption keys already exist. Use the --force option to overwrite them. Personal access client created successfully. Client ID: 2 Client Secret: MUiAhE********************** Password grant client created successfully. Client ID: 3 Client Secret: zgsEoU*****************************
    猜你喜欢
    • 2018-12-08
    • 2017-12-22
    • 2018-06-19
    • 2020-06-26
    • 2020-04-08
    • 2020-02-26
    • 1970-01-01
    • 2015-12-17
    相关资源
    最近更新 更多