laravel 6 护照中出现未经授权的 401 错误

Unauthorized 401 error in laravel 6 passport

我正在尝试使用 laravel 通行证来验证用户。我遵循了 laravel 护照文件中的每一步。但是当我访问受 'auth:api' 中间件保护的路由时它显示错误。我已经在互联网上搜索过,但到目前为止,任何答案都不起作用。请查看代码,以及我在下面尝试过的内容。

使用的技术

目前已尝试:

routes/api.php

Route::middleware('auth:api')->group(function() {
    Route::get('user', function() {
        return request()->user();
    });

    Route::get('posts', 'PostController@index')->name('posts');
    Route::post('posts/store', 'PostController@store')->name('posts.store');
    Route::get('posts/{id}/show')->name('posts.show');

    Route::get('users/{id}/show')->name('users.show');
});

Axios

mounted() {
   axios.get('/api/posts')
      .then(res => this.posts = res.data).catch(error => console.log('Unable to fetch posts.'))
}

错误

Headers:

如果您需要一些我的 post 中未指明的详细信息,请告诉我。

设置

  1. 运行 composer require laravel/passport:9 用于安装。
  2. 运行 php artisan migrate 表格。
  3. 运行 php artisan passport:install 生成加密密钥。
  4. User 模型中添加了 Laravel\Passport\HasApiTokens 特征。
  5. AuthServiceProvider 中添加了 Passport::routes();
  6. guardapi driver 更改为 config/auth.php 中的 passport

完整源代码:

Click this link

如果您使用 Api/oauth 前缀并添加 auth:api 中间件,那么您需要通过 Bearer 令牌进行身份验证。

可能是您遇到了与 csrf 令牌相关的问题,请尝试在下方禁用它。

Passport::ignoreCsrfToken(true);

您应该将令牌持有者添加到您的 ajax 请求中。登录成功即可领取。

// laravel
use Illuminate\Support\Facades\Auth;
use App\Models\User;

public function login()
{
    $credentials = request(['email', 'password']);
    $user = User::where('email', $credentials['email'])->first();

    if (!$user || !$token = Auth::attempt($credentials)) {
        return response()->json(['success'=> false, 'error' => 'неверный логин или пароль', 'cr' => $credentials], 422);
    }

    return $this->respondWithToken($token);
}

// vue login
async function login(email, password) {
  try {
    const response = await axios.post('/auth/login', {email, password});
    
    const token = response.data.token;
    
    // some func to store token, I am using vuex mutations for this
    storeToken(token);
  }
  catch(error) {
    console.error(error);
  }
};

// vue regular function
async function changePassword(newPassword) {
  // get token from global storage, with vuex it will be like store.state.auth.token
  const token = getToken();

  await axios.post('/user/changePassword', {newPassword}, headers: { Authorization: `Bearer ${token}`});
}

我认为您应该按照以下步骤检查您的代码。

步骤 1User 模型必须使用 HasApiTokens

...
class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

步骤 2Passport::routes 方法在 AuthServiceProvider

的启动方法中
class AuthServiceProvider extends ServiceProvider
{
...
    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }
}

第 3 步:在你的 config/auth.php 配置文件中,你应该将 api 身份验证保护的 driver 选项设置为 passport

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

步骤 4(可选): 如果您想从您的 JavaScript 应用程序中使用您的 API,您需要手动向该应用程序发送一个访问令牌,并将它与每个请求一起传递给您的应用程序。但是,Passport 包含一个可以为您处理此问题的中间件。您需要做的就是将 CreateFreshApiToken 中间件添加到 app/Http/Kernel.php 文件中的 web 中间件组:

'web' => [
    // Other middleware...
    \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],

!您应该确保 CreateFreshApiToken 中间件是中间件堆栈中列出的最后一个中间件。

编辑 (2021/10/17):
您应该尝试将 auth 中间件添加到 Kernel.php

$middlewareGroups
protected $middlewareGroups = [
...
  'api' => [
    'throttle:60,1',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'auth:api', //Need to add
  ],
];

编辑 (2021/10/25):
我下载了你的代码并调试了它。当你调试它时,你会得到如下结果:

Header JWT 对 JSON 结构无效。 Laravel Passport 库与您的系统似乎不兼容。您应该检查您的系统版本(PHP、Laravel 等)。我会继续调查。如果您有任何新的信息,请告诉我

编辑 (2021/11/02):

Update your laravel/framework dependency to ^6.0 in your composer.json file. If installed, update your laravel/passport dependency to ^9.3.2 in your composer.json file.

https://laravel.com/docs/6.x/upgrade#updating-dependencies

根据Laravel 6.x 文档,Laravel Passport 的版本来自 9.3.2。请试试这个版本。

您忘记了 运行 php artisan passport:keys ...so there may be no RSA key-pair available, which is crucial. Clients usually can be added with: php artisan passport:client. And generally speaking, there is no default recipe for debugging Laravel middleware ...there only is xdebug