#はじめに
フロント画面と管理画面でログイン認証を分けたい場合の
実装方法を記載する。
業務ではオリジナルテンプレートを使用するパターンが多いので、
『laravel/ui』なし、独自コントローラーでの実装を目指します。
ログイン機能を作成します。
※ログアウトやリマインダーは今回はやりません。
#やりたいこと
users:顧客
admins:管理者
別々のログイン画面でログイン認証可能にする。
#環境
PHP 7.3.2
Laravel Framework 8.5.12
MariaDB 10.1.38
#事前準備
Composerをインストール
https://weblabo.oscasierra.net/php-composer-windows-install/
#laravel8環境構築
LaravelをComposerでインストール
composer create-project --prefer-dist laravel/laravel LaravelMultiLogin "8.*"
※しばらく時間がかかります
ディレクトリ移動
cd LaravelMultiLogin
サーバ起動
php artisan serve
ブラウザでhttp://localhost:8000/
にアクセスしてLaravelって表示されれば成功
#ライブラリインストール
・fortify
composer require laravel/fortify
・laravelcollective
composer require laravelcollective/html
#各種設定
①config/app.php 言語設定変更
'timezone' => 'Asia/Tokyo',
'locale' => 'ja',
'fallback_locale' => 'ja',
'faker_locale' => 'ja_JP',`
キャッシュクリア
php artisan config:cache
②「.env」設定変更(DB接続先の環境に合わせて変更)
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db_name
DB_USERNAME=root
DB_PASSWORD=
③エラーメッセージ日本語化
下記、からダウンロード
https://github.com/Laravel-Lang/lang/tree/master/src/ja
メッセージファイルを配置
C:\XXX\LaravelMultiLogin\resources\lang\ja\auth.php
C:\XXX\LaravelMultiLogin\resources\lang\ja\pagination.php
C:\XXX\LaravelMultiLogin\resources\lang\ja\passwords.php
C:\XXX\LaravelMultiLogin\resources\lang\ja\validation-inline.php
C:\XXX\LaravelMultiLogin\resources\lang\ja\validation.php
'attributes' => [
'email' => 'メールアドレス',
'password' => 'パスワード'
],
#テーブル作成
マイグレーション作成
public function up()
{
Schema::create('admins', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
マイグレーション実行
php artisan migrate
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table
usersadd unique
users_email_unique(
email))
上記エラーが発生した場合は、下記設定をし再度実行
※一度DB内で作成されたテーブルを全て削除
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema; // 追加
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
Schema::defaultStringLength(191); // 追加
}
}
#ログインデータ作成
seedファイル作成
php artisan make:seed MultiAuthTableSeeder\MultiAuthTableSeeder.php
\DB::table('users')->insert([
[
'name' => 'user',
'email' => 'user@example.com',
'email_verified_at' => now(),
'password' => \Hash::make('password'),
'created_at' => now(),
'updated_at' => now()
],[
'name' => 'user2',
'email' => 'user2@example.com',
'email_verified_at' => now(),
'password' => \Hash::make('password'),
'created_at' => now(),
'updated_at' => now()
]
]);
\DB::table('admins')->insert([
[
'name' => 'admin',
'email' => 'admin@example.com',
'email_verified_at' => now(),
'password' => \Hash::make('123456789'),
'created_at' => now(),
'updated_at' => now()
],[
'name' => 'admin2',
'email' => 'admin2@example.com',
'email_verified_at' => now(),
'password' => \Hash::make('123456789'),
'created_at' => now(),
'updated_at' => now()
]
]);
public function run()
{
// \App\Models\User::factory(10)->create();
$this->call(MultiAuthTableSeeder::class); // 追加
}
seed実行
php artisan migrate:fresh --seed
#コンフィグファイルを変更
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admins' => [ // 追加
'driver' => 'session', // 追加
'provider' => 'admins', // 追加
], // 追加
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [ // 追加
'driver' => 'eloquent', // 追加
'model' => App\Models\Admin::class, // 追加
], // 追加
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
'admins' => [ // 追加
'provider' => 'admins', // 追加
'table' => 'password_resets', // 追加
'expire' => 60, // 追加
'throttle' => 60, // 追加
],
],
キャッシュクリア
php artisan config:cache
#モデル作成
php artisan make:model Admin -m
※Userモデルはあるため不要
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable; // 追加
class Admin extends Authenticatable // 変更
{
use HasFactory;
}
// ユーザーログイン
Route::get('user_login', [\App\Http\Controllers\UserLoginController::class, 'showLoginForm'])->name('user_login');
Route::post('user_login', [\App\Http\Controllers\UserLoginController::class, 'login']);
Route::prefix('user')->group(function () {
Route::middleware('auth:web')->group(function () {
Route::get('dashboard', function () {
Auth::guard('web')->logout();
return 'ユーザーでログイン';
});
});
});
Route::prefix('admin')->group(function () {
// 管理者ログイン
Route::get('admin_login', [\App\Http\Controllers\AdminLoginController::class, 'showLoginForm'])->name('admin.admin_login');
Route::post('admin_login', [\App\Http\Controllers\AdminLoginController::class, 'login']);
Route::middleware('auth:admins')->group(function () {
Route::get('dashboard', function () {
Auth::guard('admins')->logout();
return '管理者でログイン';
});
});
});
#コントローラー作成
php artisan make:controller UserLoginController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserLoginController extends Controller
{
//
public function showLoginForm()
{
return view('user.login');
}
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|email', 'password' => 'required',
]);
$credentials = $request->only(['email', 'password']);
if (\Auth::guard('web')->attempt($credentials)) {
return redirect('user/dashboard'); // ログインしたらリダイレクト
}
return back()->withInput($request->only('email'))
->withErrors([
'email' => ['認証情報が記録と一致しません。']
]);
}
}
#view作成
#未ログイン時のリダイレクト先変更
use Illuminate\Auth\AuthenticationException; // 追加
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['message' => $exception->getMessage()], 401);
}
if ($request->is('admin') || $request->is('admin/*')) {
return redirect('admin/admin_login');
}
return redirect('user_login');
}
unauthenticated メソッド追加
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ログイン</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" crossorigin="anonymous">
</head>
<body>
<div id="app">
<div class="container">
<div class="row justify-content-center mt-5">
<div class="col-md-6">
<div class="card">
<div class="card-header">ユーザーログイン</div>
<div class="card-body">
{{ Form::open(['method' => 'post']) }}
<div class="form-group">
{{ Form::label('email', 'メールアドレス') }}
{{ Form::text('email', null, [
'class' => 'form-control' . ($errors->has('email') ? ' is-invalid' : '')
]) }}
@error('email')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="form-group">
{{ Form::label('password', 'パスワード') }}
{{ Form::password('password', [
'class' => 'form-control' . ($errors->has('password') ? ' is-invalid' : '')
]) }}
@error('password')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div>
<button type="submit" class="btn btn-primary">ログイン</button>
</div>
{{ Form::close() }}
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
php artisan make:controller AdminLoginController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AdminLoginController extends Controller
{
//
public function showLoginForm()
{
return view('admin.login');
}
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|email', 'password' => 'required',
]);
$credentials = $request->only(['email', 'password']);
if (\Auth::guard('admins')->attempt($credentials)) {
return redirect('admin/dashboard'); // ログインしたらリダイレクト
}
return back()->withInput($request->only('email'))
->withErrors([
'email' => ['認証情報が記録と一致しません。']
]);
}
}
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ログイン</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" crossorigin="anonymous">
</head>
<body>
<div id="app">
<div class="container">
<div class="row justify-content-center mt-5">
<div class="col-md-6">
<div class="card">
<div class="card-header">管理者ログイン</div>
<div class="card-body">
{{ Form::open(['method' => 'post']) }}
<div class="form-group">
{{ Form::label('email', 'メールアドレス') }}
{{ Form::text('email', null, [
'class' => 'form-control' . ($errors->has('email') ? ' is-invalid' : '')
]) }}
@error('email')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="form-group">
{{ Form::label('password', 'パスワード') }}
{{ Form::password('password', [
'class' => 'form-control' . ($errors->has('password') ? ' is-invalid' : '')
]) }}
@error('password')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div>
<button type="submit" class="btn btn-primary">ログイン</button>
</div>
{{ Form::close() }}
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
#参考記事
https://blog.capilano-fw.com/?p=8159
https://www.webopixel.net/php/1665.html