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

Posted

技术标签:

【中文标题】laravel 6护照中未经授权的401错误【英文标题】:Unauthorized 401 error in laravel 6 passport 【发布时间】:2021-11-30 13:58:54 【问题描述】:

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

使用的技术

Laravel 6 Laravel 护照 Vue 2 Axios

目前尝试过:

AuthServiceProvider 中将Passport::routes(); 更改为Passport::routes(null, ['prefix' => 'api/oauth', 'middleware' => ['auth:api', 'web', 'auth']]);。也试过Passport::routes(null, ['prefix' => 'api/oauth'); 试图运行php artisan cache:clear

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.'))

错误

标题:

如果您需要一些我的帖子中没有说明的细节,请告诉我。

设置

    运行composer require laravel/passport:9 进行安装。 为表格运行 php artisan migrate。 运行php artisan passport:install 生成加密密钥。 在User 模型中添加了Laravel\Passport\HasApiTokens 特征。 在AuthServiceProvider 中添加了Passport::routes();。 在config/auth.php 中将guardapi 驱动程序更改为passport

完整源代码:

Click this link

【问题讨论】:

能否提供更多详细信息,如何设置 laravel 护照? @Dmitry 请在我的帖子中查看我的更新。 【参考方案1】:

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

第 1 步User 模型必须使用 HasApiTokens

...
class User extends Authenticatable

    use HasApiTokens, Notifiable;

第 2 步Passport::routes 方法在您的AuthServiceProvider 的引导方法中

class AuthServiceProvider extends ServiceProvider

...
    public function boot()
    
        $this->registerPolicies();

        Passport::routes();
    

第3步:在你的config/auth.php配置文件中,你应该将api authentication guard的驱动选项设置为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 日): 您应该尝试将身份验证中间件添加到您的Kernel.php$middlewareGroups

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

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

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

编辑(2021/11/02):

在您的 composer.json 文件中将您的 laravel/framework 依赖项更新为 ^6.0。如果已安装,请将您的 laravel/passport 依赖项更新为 composer.json 文件中的 ^9.3.2。

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

根据 Laravel 6.x 文档,Laravel Passport 的版本是从 9.3.2 开始的。请试试这个版本。

【讨论】:

这正是我的设置。但奇怪的是我仍然收到Unauthenticated (401) 错误。我也尝试将护照升级到版本9.*,但仍然遇到同样的错误。 我已经更新了我的帖子。 我仍然遇到同样的错误。 @Jie You 尝试升级到 Passport v9.3.2。如果您有任何问题,请告诉我。 说真的!?更改护照版本有效!知道为什么吗?请编辑您的答案,以便我接受它【参考方案2】:

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

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

Passport::ignoreCsrfToken(true);

【讨论】:

我仍然遇到同样的错误。我在Passport::routes(); 之后的AuthServiceProvider 中添加了该代码 我想你错过了一些护照安装的步骤。请检查laravel.com/docs/6.x/passport 的所有步骤,您应该在 App\Providers\AuthServiceProvider 的引导方法中调用 Passport::routes 方法。此方法将注册颁发访问令牌和撤销访问令牌、客户端和个人访问令牌所需的路由:【参考方案3】:

您应该将令牌持有者添加到您的 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`);

【讨论】:

【参考方案4】:

您忘记运行php artisan passport:keys ...因此可能没有可用的 RSA 密钥对,这一点至关重要。客户通常可以添加:php artisan passport:client。而且一般来说,调试 Laravel 中间件没有默认配方……只有xdebug

【讨论】:

我相信php artisan passport:keys只有当你在生产服务器上部署它的时候。这是基于文档:laravel.com/docs/6.x/passport#deploying-passport

以上是关于laravel 6护照中未经授权的401错误的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 护照、vueJS 和 Axios 中获得未经授权的 401

Laravel 护照 oauth 路线总是返回 401 未经授权

在Laravel护照,vueJS和Axios中未经授权获得401

401 未经授权使用带有 Laravel Passport 的不记名令牌

护照-jwt 401 未经授权

护照-jwt 总是返回“未经授权” - 401