Laravel 5.5 - Вход на сайт из разных БД или разных таблиц одной БД
Как организовать вход на сайт из нескольких таблиц БД или из нескольких БД
При создании проекта на Laravel иногда возникает необходимость организовать вход на сайт (Аутентификацию) из разных таблиц. Для чего это может потребоваться? Например:
- для простого пользователя вход на сайт производить из таблицы User а для администратора из таблицы Admin
- при реализации некоего независимого раздела на сайте, на под-домене к примеру
Как в Laravel можно организовать аутентификацию из нескольких мест. Для начала давайте рассмотрим пример входа на сайт из разных таблиц одной БД.
Аутентификация на сайте из разных таблиц одной БД
Сначала реализуем стандартную авторизацию Laravel, на этом не будем останавливаться, в доках все есть.
Создаем в дополнение к таблице User аналогичную таблицу Admin:
php artisan make:migration create_admins_table
Сама миграция может выглядеть так:
<?php use IlluminateSupportFacadesSchema; use IlluminateDatabaseSchemaBlueprint; use IlluminateDatabaseMigrationsMigration; class CreateAdminsTable extends Migration { public function up() { Schema::create('admins', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } public function down() { Schema::drop('admins'); } }
Запускаем миграцию:
php artisan migrate
Таблица Admins полный аналог таблицы Users, за исключением названия.
Дальше создаем модель для админа и положим ее в папку Admin:
php artisan make:model AdminAdmin
В самом минимальном виде модель админа будет работать в таком виде:
<?php namespace AppAdmin; use IlluminateNotificationsNotifiable; use IlluminateFoundationAuthUser as Authenticatable; class Admin extends Authenticatable { use Notifiable; protected $table = 'admins'; protected $fillable = ['name', 'email', 'password',]; protected $hidden = ['password', 'remember_token',]; }
Дальше создаем контроллер для аутентификация админа LoginController, положим его в папку ControllersAdminAuth:
php artisan make:controller AdminAuthLoginController
Простейшая реализация контроллера:
<?php namespace AppHttpControllersAuthAdmin; use IlluminateHttpRequest; use AppHttpControllersController; use IlluminateFoundationAuthAuthenticatesUsers; use Auth; class LoginController extends Controller { use AuthenticatesUsers; public function showLoginForm() { return view('admin.auth.login'); }public function login(Request $request) { if(Auth::guard('admin')->attempt([ 'email' => $request->get('email'), 'password' => $request->get('password') ], $request->filled('remember'))) { return redirect()->route('admin'); } return redirect()->back()->with('status', 'Неправильный логин или пароль'); } public function logout() { Auth::guard('admin')->logout(); return redirect()->back(); } }
В этом коде основная магия происходит в конструкции Auth::guard(«admin»).
Не станем останавливаться на создании представления, это просто. Двигаемся дальше.
Дальше, этот guard(«admin») нужно прописать в файле config/auth.php.
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], 'admin' =>[ 'driver' => 'session', 'provider' => 'admin', ] ],'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => AppUser::class, ], 'admin' => [ 'driver' => 'eloquent', 'model' => AppAdminAdmin::class, ] ],
Осталось только прописать маршруты в файле routes/web.php.. Здесь есть маленький нюанс.
Route::get('/', 'HomeController@index')->name('home'); // Логиниться могут только незалогиненные пользователи. // В мидлвер нужно прописать наш созданный гвард: 'guest:admin', // если оставить просто 'guest' - работать не будет. Route::group(['middleware' => 'guest:admin'], function(){ Route::get('/login', 'AdminAuthLoginController@showLoginForm')->name('login'); Route::post('/login', 'AdminAuthLoginController@login')->name('loginForm'); }); // Разлогиниться могут только залогиненные пользователи. // В мидлвер нужно прописать наш созданный гвард: 'auth:admin', // если оставить просто 'auth' - работать не будет. Route::group(['middleware' => 'auth:admin'], function(){ Route::get('/logout', 'AdminAuthLoginController@logout')->name('logout'); }); // Маршруты для админки, на свое усмотрение. Route::group(['prefix' => 'admin', 'namespace' => 'Admin', 'as' => 'admin.', 'middleware' => 'admin'], function(){ Route::get('/', 'DashboardController@index')->name('dashboard'); });
Достучаться до админа теперь можно также используя наш созданный гвард:
Auth::guard('admin')->user()Auth::guard('admin')->user()->idAuth::guard('admin')->check()
Вот собственно и все. Это самый минимально необходимый код для реализации аутентификации из разных таблиц одной БД. А теперь давайте рассмотрим вариант аутентификации из разных БД.
Аутентификация на сайте из разных БД
Если возникла необходимость входа на сайт, используя разные БД, необходимо внести небольшие коррективы в выше описанный код. Изменений очень мало.
Создаем новую БД под названием к примеру Admin, и создаем в ней таблицу User.
Потом создаем дополнительное подключение к БД, идем в файл config/database.php и прописываем подключение к еще одной БД и называем его например 'mysql-admin«.
'connections' => [ 'sqlite' => [ 'driver' => 'sqlite', 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', ], 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], 'mysql-admin' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => 'Admin', 'username' => 'root', 'password' => '', 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], ],
Немного изменим секцию »providers' в файле config/auth.php, заменим 'model' => AppAdminAdmin::class, на 'model' => AppAdminUser::class
'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => AppUser::class, ], 'admin' => [ 'driver' => 'eloquent', 'model' => AppAdminUser::class, ] ],
Заменим Модель Admin на User и будем это подключение использовать в модели
<?php namespace AppAdmin; use IlluminateNotificationsNotifiable; use IlluminateFoundationAuthUser as Authenticatable; class User extends Authenticatable { use Notifiable; protected $connection = 'mysql-admin'; protected $table = 'users'; protected $fillable = ['name', 'email', 'password',]; protected $hidden = ['password', 'remember_token',]; }
Остальной код, описанный выше, оставляем без изменений.
Вот таким нехитрым образом можно организовать в Laravel авторизацию из разных таблиц и разных БД.
Удачи, если кому-то пригодится, буду очень рад.