Laravel multi auth и авторизуйте ресурс

У меня проблема со следующим сценарием, и я надеюсь найти здесь совет:

Я установил Laravel 5.7 и запустил make: auth для лесов аутентификации. Родная модель User была удалена, и вместо этого я использую две пользовательские модели: «Клиент» и «Администратор» (миграции были изменены соответственно).

Модель администратора:

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Traits\FormatUserdata;

class Admin extends Authenticatable
{
use Notifiable, FormatUserdata;

protected $guard = 'admin';

/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'firstname', 'lastname', 'email', 'password',
];

/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}

Модель клиента:

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Traits\FormatUserdata;

class Customer extends Authenticatable
{
use HasApiTokens, Notifiable, FormatUserdata;

protected $guard = 'customer';

protected $fillable = [
'firstname', 'lastname', 'email', 'company', 'address', 'zip', 'city', 'country', 'vatid', 'customer_no', 'password',
];

protected $hidden = [
'password', 'remember_token',
];

public function licenses()
{
return $this->hasMany('App\License');
}
}

Поэтому я должен аутентифицировать пользователей из двух разных моделей и таблиц. Чтобы это работало, я изменил свой config / auth.php следующим образом:

return [
'defaults' => [
'guard' => 'customer',
'passwords' => 'customers',
],

'guards' => [
'customer' => [
'driver' => 'session',
'provider' => 'customers',
],

'admin' => [
'driver' => 'session',
'provider' => 'admins',
],

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

'providers' => [
'customers' => [
'driver' => 'eloquent',
'model' => App\Customer::class,
],

'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],

'passwords' => [
'customers' => [
'provider' => 'customers',
'table' => 'password_resets',
'expire' => 60,
],

'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
],
],

];

Для моей модели Customer я настроил контроллер ресурсов, который защищен политикой ресурсов, а также промежуточное программное обеспечение для метода index:

namespace App\Http\Controllers;

use App\Customer;
use Illuminate\Http\Request;

class CustomerController extends Controller
{
public function __construct()
{
$this->middleware('auth:admin')->only('index');
$this->authorizeResource(Customer::class);
}

public function show(Customer $customer)
{}

...shortened

}

Вот политика, на которую я ссылаюсь в этом контроллере:

namespace App\Policies;

use App\Customer;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Foundation\Auth\User;

class CustomerPolicy
{
use HandlesAuthorization;

public function view(User $user, Customer $customer)
{
return true;
}

}

Мои маршруты не имеют никакого дополнительного промежуточного программного обеспечения.

Вот проблема:

Когда я захожу на свой маршрут / клиенты / 1 с пользователем по умолчанию охранника «клиент», все работает как положено (без ошибок). Однако, когда я пытаюсь получить доступ к этому маршруту с правами администратора, я получаю 403 несанкционированный ответ. Странно то, что когда я пытаюсь проверить разрешения в представлении с

@can('view', App\Customer::findOrFail(3))

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

У кого-нибудь есть идеи, как решить эту проблему?

Спасибо!
Andreas

редактировать:

Вот мой AuthServiceProvicer.php:

namespace App\Providers;

use App\Policies\CustomerPolicy;
use App\Customer;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
Customer::class => CustomerPolicy::class
];

public function boot()
{
$this->registerPolicies();
}
}

А вот мои маршруты / web.php

Route::get('/', function () {
return view('welcome');
});

Auth::routes(['register' => false]);

Route::prefix('admin')->name('admin.')->group(function () {
Route::get('/', function () {
return redirect( route('admin.dashboard') );
});

Route::get('dashboard', 'AdminController@dashboard')->name('dashboard');
Route::get('login', 'Auth\AdminLoginController@showLoginForm')->name('login');
Route::post('login', 'Auth\AdminLoginController@login')->name('login.post');
Route::post('logout', 'Auth\AdminLoginController@logout')->name('logout');

Route::post('password/email', 'Auth\AdminForgotPasswordController@sendResetLinkEmail')->name('password.email');
Route::get('password/reset', 'Auth\AdminForgotPasswordController@showLinkRequestForm')->name('password.request');
Route::post('password/reset', 'Auth\AdminResetPasswordController@reset')->name('password.update');
Route::post('password/reset/{token}', 'Auth\AdminResetPasswordController@showResetForm')->name('password.reset');

Route::resource('customers', 'CustomerController');
});

Route::prefix('backend')->name('backend.')->group(function () {
Route::get('/', function () {
return redirect( route('backend.dashboard') );
});
Route::get('dashboard', 'BackendController@dashboard')->name('dashboard');
Route::resource('customers', 'CustomerController')->except([
'index'
]);

});

Поэтому для клиентов я использую маршрут / бэкэнд / customer / {customer}, а для администраторов я использую маршрут / admin / customer / {customer}

0

Решение

После нескольких дальнейших исследований я наткнулся на этот потрясающий пост в блоге.

https://medium.com/@JinoAntony/multi-user-authentication-using-guards-in-laravel-5-6-f18b4e61bdde

Важным шагом здесь является создание дополнительного промежуточного программного обеспечения «AssignGuard», которое устанавливает охрану в зависимости от используемого маршрута.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]