Ошибка при загрузке ролей с разрешениями пользователей laravel

При попытке загрузить роли с назначенными пользователями из библиотеки laravel-permissions Spatie, как это

use Spatie\Permission\Models\Role;

Role::with('users')->get();

Эта ошибка возникает

Ошибка: имя класса должно быть допустимым объектом или строкой в ​​файле vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php в строке 791.

Приведенный выше код отлично работает в Laravel PsySH с питанием от Repl Tinker , см. этот пост StackOverflow

Поэтому я подумал, что если это происходит только в HTTP-запросах, это должно быть связано с проблемой промежуточного программного обеспечения.

Я использую Laravel Sanctum для аутентификации API, поэтому маршрут находится под промежуточным программным обеспечением auth:sanctum

в routes/api.php

Route::middleware('auth:sanctum')->group(function () {
  Route::get('/roles', [RolesController::class, 'index']);
});

Это также работает, если я перемещаю маршрут из промежуточного программного обеспечения, но я не должен этого делать, поскольку только аутентифицированные пользователи должны иметь доступ к этой конечной точке.

Я предполагаю, что это как-то связано с тем, что роли создаются с помощью guard_name as web в базе данных по умолчанию, но я не уверен, как это исправить.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

ТЛ; ДР?

в config/auth.php добавьте это в массив guards

'sanctum' => [
  'driver' => 'sanctum',
  'provider' => 'users'
],

Объяснение

Проблема в том, что поставщик услуг Sanctum устанавливает защиту аутентификации со значением null для поставщика, см. исходный код здесь

class SanctumServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        config([
            'auth.guards.sanctum' => array_merge([
                'driver' => 'sanctum',
                'provider' => null, // <=== This is the issue
            ], config('auth.guards.sanctum', [])),
        ]);

        if (! app()->configurationIsCached()) {
            $this->mergeConfigFrom(__DIR__.'/../config/sanctum.php', 'sanctum');
        }
    }

Это вызывает вспомогательную функцию getModelForGuard() Laravel-Permission здесь

function getModelForGuard(string $guard)
{
    return collect(config('auth.guards'))
        ->map(fn ($guard) => isset($guard['provider']) ? config("auth.providers.{$guard['provider']}.model") : null)
        ->get($guard);
}

ничего не возвращать, когда промежуточное ПО требует аутентификации охранника Sanctum, поэтому нетерпеливая загрузка не удалась здесь

/**
 * A role belongs to some users of the model associated with its guard.
 */
public function users(): BelongsToMany
{
    return $this->morphedByMany(
        // Error occurs here
        getModelForGuard($this->attributes['guard_name'] ?? config('auth.defaults.guard')),
        'model',
        config('permission.table_names.model_has_roles'),
        app(PermissionRegistrar::class)->pivotRole,
        config('permission.column_names.model_morph_key')
    );
}

После ручной вставки защиты в auth/config.php с подходящим провайдером активная загрузка снова работает.

'guards' => [
    ...

    'sanctum' => [
        'driver' => 'sanctum',
        'provider' => 'users'
    ]
],

Другие вопросы по теме