Laravel Passport:应用程序中的CreateFreshApiToken:授权失败

时间:2018-12-18 23:24:57

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

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

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

我在JavaScript Web应用程序中收到401未经授权的错误。我已经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: enter image description here

与邮递员的工作要求: enter image description here

2 个答案:

答案 0 :(得分:1)

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

  

强烈建议您使用   Angular,React.js或Vue.js,然后是SPA(单页应用程序)   该方法将产生更强大的产品。

     

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


  

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

     

如果您的应用程序在同一域中,则无需使用   护照。相反,本机会话cookie身份验证完全可以,   您要做的就是确保您传递的是CSRF令牌   请求。


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

根据该指南,当您成功向/oauth/token请求时,应在应用程序中将返回的令牌设置为带有Bearer令牌的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

答案 1 :(得分:-1)

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

php artisan passport:install

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

Laravel 5.7 Passport docs