リファレンスサイト
Breaze認証
作成するlaravelのui認証機能一覧
- ログイン機能
- パスワードのリセット機能
- Email Verification機能(登録されたメールの確認機能)
- メールの実在性の確認
- ログインかつメール認証済みのユーザだけを許可する認証ができる。
- password confirm機能(再度passwordの再確認を求める)
認証機能はuserとadminで別々に作成します。
larabelのインストール
laravel new laravel-multi-auth
ui認証機能のインストール
composer require laravel/ui:^3.3
php artisan ui bootstrap --auth
npm install && npm run dev
npm run dev
user認証を作成する
usersテーブを作成するだけ
データベースはsqlite
#データベースをmySqlからsqliteに変更
DB_CONNECTION=sqlite
# DB_CONNECTION=mysql
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
- database.sqliteファイル の作成
type nul > database/database.sqlite
- 環境変数にgitを通していたら
windows
でもtoouch
コマンドが使える。
touch database/database.sqlite
php artisan migrate
認証リンク
user登録画面
user登録するとusersテーブルにデータが登録されて
sql viewer
登録されたデータでログインできる。
リメンバーミーにチェックをいれる。セッションが切れても次回アクセス時自動でログインしてくれる。
セッション時間はデフォルトで2時間
リメンバーミーを設定すると5年
//config\app.php
//session時間
'lifetime' => env('SESSION_LIFETIME', 120),
//env
SESSION_LIFETIME=120
//config\session.php
//ブラウザをクローズした時,sessionを(true:切る)(false:切らない)
'expire_on_close' => false,
//クッキーの名前
'cookie' => 'laravel_session',
//remember meで延長される時間 5年 2628000分<-変更する時はこの数字を変更する
public function forever($name, $value, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null)
{
return $this->make($name, $value, 2628000, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
}
パスワードリセットを確認をする。(forget passwordリンク).
メール送信のための環境設定
googleメールを使用する。
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=グーグルのメール
MAIL_PASSWORD=123456789
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=グーグルのメール(適当なメールでもOK,but必要null値はerrorになる)
MAIL_FROM_NAME="٩(♡ε♡ )۶of٩(♡ε♡ )۶"
**MailTrap**のダミーのSMTPサーバを使用する
リンクをクリックするとメールアドレスの入力フォームが表示される
resources\views\auth\passwords\email.blade.php
データベースにアドレスがなければエラーになる
あれば、メールを送信しましたとのアラートが表示される
送られてきたメールのリンクをクリックすると、
パスワードの再入力画面が表示される
resources\views\auth\passwords\reset.blade.php
パスワードが再設定されログインされる。
resources\views\home.blade.php
mail Verification機能
- 非検証のメールから検証済みのメールへ変更する。
ユーザーモデルにimplements MustVerifyEmail を追記
// class User extends Authenticatable
class User extends Authenticatable implements MustVerifyEmail
ユーザー登録時メールの確認も行う場合
[verify=>true]
をAuth::routes()
に追加
//Auth::routes()
Auth::routes(['verify' => true]);
登録が完了すると
普通にログインできる。
ただ、メールが送られてくるのでリンク先にアクセスすると。
メールの検証が完了する。テーブルに検証時間が入る。
メール検証済みのユーザーのみが許可されるルートを作成する。
Route::get('/test', function () {
return 'メールは検証済みです。';
})->middleware(['verified']);
検証済みのユーザーがアクセスすると
未検証のユーザーがアクセスすると
リダイレクトされる。リンクをクリックすると。
未検証のメール宛にメールが送信される。
送られてきたメールのリンクにアクセスすると検証済みのメールになり、サイトに許可される。
password.confirm
- ユーザのパスワードの再確認を求めるルート
//middleware(['auth', 'password.confirm'])をはってやる。必ずauthとセット
Route::get('/confirmed', function () {
return 'パスワードの確認';
})->middleware(['auth', 'password.confirm']);
アクセスするとパスワードの再入力画面にリダイレクトされる。
確認されるとアクセスサイトにリダイレクトされる。
その他パスワードのリセットをすると、password_resetsテーブルにメールアドレスとトークンと時間が記録される。時間内にメールのリンクにアクセスすると、
パスワードのリセットが完了すると消去される。
マルチ認証を実装する
- 修正1⃣
- メールのviewsと宛先の修正。
- 修正2⃣
- ルートの修正
- これは作成と同時に修正されるので修正は不要
- ルートの修正
- 修正3⃣
- viewsのリンクの宛先の修正
- 修正4⃣
- コントローラーでリターンするviewsを修正
- 修正5⃣
- ガードとモデルを修正する
- 修正6⃣
- ミドルウェアのリダイレクト先の修正
➀,➁,➂ guardとmodelを作成(コピペ)する
- まず、2種類のログイン機構が存在するため、ガードを2つに分けます。
- それぞれのテーブルを管理するモデルが必要なためモデルも2つに分ける
必然的に、ログイン対象のモデルを管理している「プロバイダ」も2つに分ける - プロバイダーが分かれたため、パスワードのリセットも分ける。
認証を新たに追加する。
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
//+provider+driver(session)がguardになる。
'admin-web'=>[
'driver' => 'session',
'provider' => 'admins',
]
],
◎providerはmodelを組み込んでいるため、modelが異なると区分する必要がある。
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
//+これがguardではなく、上のadmin-webがguardになる。
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
◎パスワードリセットの設定もプロバイダーとセットになっているため、
区分する必要がある
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
//+ return Password::broker('admins');の時の名前
'admins' => [
//消去するプロバイダー
'provider' => 'admins',
'table' => 'password_resets',//テーブルを分ける場合はここを修正 'admin_password_resets'とかにする。
//リセットパスワードメールの有効時間(分)
'expire' => 60,//一時間
'throttle' => 60,
],
],
感覚的にはプロバイダーのadminがguardだが、
実際はその上のガードドライバ(session)を含むadmin-webがguardになる。
Adminモデルとadminsテーブルを作成する
php artisan make:model Admin -mf
//今回は機能をそのままコピペするため、usersテーブルをそのままコピペ。
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
認証系のAdminモデルはAuthenticatableを必ず継承して作成する。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
//+
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
// class Admin extends Model
class Admin extends Authenticatable implements MustVerifyEmail
{
//+
use HasApiTokens, HasFactory, Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
修正5⃣ メールのviewsと宛先の変更
Authenticatableを継承して作成するため、メールの返信先のリンクを変更する必要がある。
modelから送るメールを修正する。
返信先のアドレスをadminに変更する。
- パスワードのリセットメールの修正
- 検証メールの修正
1.パスワードのリセットメールの宛先を修正する
- 送り先を adminsテーブルのユーザーに修正するため
php artisan make:notification ResetPasswordAdminNotification
app\Models\Admin.php
use App\Notifications\ResetPasswordAdminNotification;
---------------------
//リセットパスワードを送るメソッド
public function sendPasswordResetNotification($token)
{
//作成したクラスに変更する 引数はtokenと返信先のルート(url)とresetPasswordConfig
$this->notify(new ResetPasswordAdminNotification($token, 'admin.password.reset', 'admins'));
}
ResetPasswordAdminNotificationを編集する。
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Auth\Notifications\ResetPassword;
// class ResetPasswordAdminNotification extends Notification
class ResetPasswordAdminNotification extends ResetPassword //修正
{
use Queueable;
public $resetPasswordRoute;
public $resetPasswordConfig;
public function __construct($token, $resetPasswordRoute = null, $resetPasswordConfig = null)
{
parent::__construct($token);
$this->resetPasswordRoute = $resetPasswordRoute;
$this->resetPasswordConfig = $resetPasswordConfig;
}
//$notifiableはモデルが入っている。
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
if (static::$createUrlCallback) {
$url = call_user_func(static::$createUrlCallback, $notifiable, $this->token);
} else {
//これが返信用のアドレス。引数でルート名'admin.password.reset'を渡している。
$url = route($this->resetPasswordRoute,[
'token' => $this->token,
'email' => $notifiable->getEmailForPasswordReset(),
]);
}
//メールの内容
return (new MailMessage)
->subject('主題:パスワードリセットについてや')
->line('リクエスト要求があったらからメールをおくった')
//返信用URLのactionボタン
->action('パスワード変更サイトへGO', $url)
->line("このパスワードの有効期限は".config('auth.passwords.admins.expire')."期間です")
->line('見覚えがなかったら無視してくれ。');
}
}
2.検証メールの宛先の修正
php artisan make:notification VerifyEmailNotification
//+
use App\Notifications\VerifyEmailNotification;
----
//+
public function sendEmailVerificationNotification()
{
// 引数は 返信用のリンクの Uri
$this->notify(new VerifyEmailNotification('admin.verification.verify'));
}
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\URL;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Config;
use Illuminate\Notifications\Messages\MailMessage;
// class VerifyEmailNotification extends Notification
class VerifyEmailNotification extends VerifyEmail //修正
{
use Queueable;
protected $verifyEmailRoute; //追記
//引数でルートを渡している。$this->notify(new XXX($token, 'admin.password.reset', 'admins'))
public function __construct(/*追記*/$verifyEmailRoute/*='admin.verification.verify'*/)
{
$this->verifyEmailRoute = $verifyEmailRoute; //追記
}
protected function verificationUrl($notifiable)
{
// 時間制限付きのリンク の作成
return URL::temporarySignedRoute(
$this->verifyEmailRoute,
Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
[
'id' => $notifiable->getKey(),
'hash' => sha1($notifiable->getEmailForVerification()),
]
);
}
// 引数の$url には $this->verifyEmailRoute が 渡る。
protected function buildMailMessage($url)
{
return (new MailMessage)
->subject('メールアドレスの確認')
->line('以下のボタンをクリックして、メールアドレスの確認をしてください。')
->action('メールアドレスの確認', $url)
->line('アカウントを作成されていない場合は、これ以上の操作は必要ありません。');
}
}
Admin authのルートを作成する。
- 修正は不要 - 修正2⃣ に該当する
//uri,コントローラー,nameの重複をgroupで解消
Route::group(['prefix' => '/admin', 'namespace' => 'Admin', 'as' => 'admin.'], function () {
Auth::routes(['verify' => true]);
});
Admin authのコントローラーとviewsを作成する
Admin authのControllerを作成する
- AuthディレクトリをAdminディレクトリの下にコピー
xcopy app\Http\Controllers\Auth app\Http\Controllers\Admin\Auth/e/i
- homeコントローラーをAdminディレクトリの下にコピー
copy app\Http\Controllers\HomeController.php app\Http\Controllers\Admin\HomeController.php
Admin authのviewsを作成する
- authディレクトリをAdminディレクトリの下にコピー
xcopy resources\views\auth resources\views\admin\auth/e/i
- home.blade.phpをAdminディレクトリの下にコピー
copy resources\views\home.blade.php resources\views\admin
- welcome.blade.phpをAdminディレクトリの下にコピー
copy resources\views\welcome.blade.php resources\views\admin
- app.blade.phpのファイルをコピーしてファイル名をadmin_app.blade.phpに変更する
copy resources\views\layouts\app.blade.php resources\views\layouts\admin_app.blade.php
Admin authのコントローラーとviewsのリンクの宛先を修正する。
Admin Authコントローラーを修正する。
- コントローラーの階層を変更したため、ネームスペースを変更する。
- リダイレクト先をroute('admin.home')に変更する
- veiwsをauthからAdmin/authに変更
- guradをwebからweb-adminに変更
- providerをusersからadminsに変更
- passwordsをusersからadminsに変更
- middlewareのリダイレクト先をAdmin/authへ変更。
1.階層を変更したため、ネームスペースを変更する。
// namespace App\Http\Controllers\Auth;
namespace App\Http\Controllers\Admin\Auth;
// namespace App\Http\Controllers;
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller; //追記
2.リダイレクト先をAdmin/authに変更する
protected $redirectTo = RouteServiceProvider::ADMIN_HOME;
RouteServiceProviderにADMIN_HOMEを追加
//ついでに追加 laravel8対策 コントローラーをフル表記しなくてすむ。
protected $namespace = 'App\Http\Controllers'; //追記
public const HOME = '/home';
public const ADMIN_HOME = '/admin/home';//追記
3.veiwsをauthからAdmin/authに変更
Admin/Auth/Controllerのreturn view
をreturn view('auth.*')
から
return veiw('admin.auth.*')
に変更する
passwordの再確認を行うviewをAdmin/auth/*に変更する
password/confirm.blade.php
public function showConfirmForm()
{
return view('admin.auth.passwords.confirm');
}
リセットパスワードのemailの再入力画面をAdmin/auth/*に変更する。
password/email.blade.php
public function showLinkRequestForm()
{
return view('admin.auth.passwords.email');
}
ログインフォームとログアウト後の遷移先ををAdmin/auth/*に変更する。
login.blade.php
use Illuminate\Http\Request;//ファザードではない。
use Illuminate\Http\Response;
//adminのログインフォームを表示
public function showLoginForm()
{
return view('admin.auth.login');
}
//adminサイトを表示させる。ログアウトしたらurl('/admin')へリダイレクト
protected function loggedOut(Request $request)
{
// $request->wantsJson()は、ヘッダーX-Requested-Withを必要とせずにaxiosクエリをチェックします。
//($requext->ajax())
return $request->wantsJson()
? new Response('', 204)
: redirect('/admin');
}
レジスター登録画面をAdmin/auth/*に変更する。
register.blade.php
// return veiwを修正
public function showRegistrationForm()
{
return view('admin.auth.register');
}
リセットパスワードの返信先の画面をAdmin/auth/*に変更する。
password/reset.blade.php
use Illuminate\Http\Request;
------
//追記 return veiwの変更
public function showResetForm(Request $request, $token = null)
{
return view('admin.auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
検証メールの確認を求める画面をAdmin/auth/*に変更する。
verify.blade.php
use Illuminate\Http\Request;
------------
//追記 return viewの変更
public function show(Request $request)
{
return $request->user('admin-web')->hasVerifiedEmail()
? redirect($this->redirectPath())
: view('admin.auth.verify');
}
ホーム画面をAdmin/auth/*に変更する。
home.blade.php
public function index()
{
return view('admin.home');//修正
}
guradをwebからweb-adminに変更
認証動作を伴うコントローラー
- LoginController.php
- RegisterController.php
- ResetPasswordController.php
providerをusersからadminsに変更する
テーブルに登録動作を行うコントローラー
- RegisterController.php
passwordsをusersからadminsに変更する
パスワードリセットを伴うコントローラー
- ForgotPasswordController.php
- ResetPasswordController.php
use Illuminate\Support\Facades\Auth;
---------
//認証(ガード)をwebからadmin-webに変更してやる。
protected function guard()
{
return Auth::guard('admin-web');
}
//+
use App\Models\Admin;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
--------------
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
// 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
//ユニークの参照先テーブルを変更
'email' => ['required', 'string', 'email', 'max:255', 'unique:admins'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
//登録先をAdminへ変更
protected function create(array $data)
{
return Admin::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'api_token' => Str::random(80),
]);
}
//認証はadmin-webに変更
protected function guard()
{
return Auth::guard('admin-web');
}
//+
use Illuminate\Support\Facades\Auth;
------------
//認証はadmin-webに変更
protected function guard()
{
return Auth::guard('admin-web');
}
//パスワードリセットのpasswordsをusersからadminsに変更
//Adminモデルに変更される。
public function broker()
{
return Password::broker('admins');
}
use Illuminate\Support\Facades\Password;
--------
//パスワードリセットのpasswordsをusersからadminsに変更
public function broker()
{
return Password::broker('admins');
}
middlwareをwebからadmin-webへ変更する。
defaultのwebは省略されている。
- middleware('auth')
- 未ログイン中ににアクセスするとlogin画面にリダイレクトさせる。
- middleware('guest')
- ログイン中にアクセスするとhome画面にリダイレクトさせる。
- ConfirmPasswordController.php
- VerificationController.php
- HomeController.php//忘れずに
//$this->middleware('auth');
$this->middleware('auth:admin-web');
- LoginController.php
// $this->middleware('guest')->except('logout');
$this->middleware('guest:admin-web')->except('logout');
- RegisterController.php
// $this->middleware('guest');
$this->middleware('guest:admin-web');
middlewareのリダイレクト先を修正する
- middlewareの設定はApp\Http\Kernel.phpに記述されている.
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
よって
-
middleware('auth')
は
app\Http\Middleware\Authenticate.php
を修正する -
middleware('guest')
は
app\Http\Middleware\RedirectIfAuthenticated.php
を修正する
middleware('auth')
を修正する
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Auth\AuthenticationException;
class Authenticate extends Middleware
{
//下で追加した引数を追加。
//引数はmiddleware('auth:追記1,追記2,追記3,・・・')といくらでも追加できる。
//protected function redirectTo($request)
protected function redirectTo($request, $guards=null)
{
if (!$request->expectsJson()) {
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if ($guard == 'admin-web') {
// リダイレクトするルートを返してやる。
return route('admin.login');
}
}
return route('login');
}
}
//+
function unauthenticated($request, array $guards)
{
// 未認証なら スローされる。
throw new AuthenticationException(
// 修正
// 'Unauthenticated.', $guards, $this->redirectTo($request)
'Unauthenticated.',
$guards,
//$this->redirectTo()関数の引数に array $gurdsを追記してやる。
$this->redirectTo($request, $guards)
);
}
}
2.middleware('guest')
を修正する
<?php
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
// $guardはmiddlewareの引数
//->middleware(['guest:追記1,追記2,追記3']);今回は追記1だけなので、...$guardsから$guardに修正
public function handle(Request $request, Closure $next, $guard = null/*...$guards*/)
{
//1個だけなので繰り返す必要もない。
// $guards = empty($guards) ? [null] : $guards;
// foreach ($guards as $guard) {
// if (Auth::guard($guard)->check()) {
// return redirect(RouteServiceProvider::HOME);
// }
// }
//もうすでに認証ずみなら、拒否して各々にリダイレクトさせる。
if (Auth::guard($guard)->check()) {
switch ($guard) {
case 'admin-web':
return redirect(RouteServiceProvider::ADMIN_HOME);
default:
return redirect(RouteServiceProvider::HOME);
}
}
return $next($request);
}
}
その他、ミドルウェアを修正する。
3.middleware('verified')--検証済みのユーザーだけ許可
php artisan make:middleware EnsureEmailIsVerified
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Redirect;
class EnsureEmailIsVerified
{
//middleware(['verified:admin.verification.notice,admin-web'])
//$redirectToRoute = 'admin.verification.notice',
//$guard = 'admin-web'
// $guard の追加
//public function handle($request, Closure $next, $redirectToRoute = null)
public function handle($request, Closure $next, $redirectToRoute = null, $guard = null)
{
// if (! $request->user() ||
// ($request->user() instanceof MustVerifyEmail &&
// ! $request->user()->hasVerifiedEmail())) {
if (
// $guard の追加
!$request->user($guard) ||
($request->user($guard) instanceof MustVerifyEmail &&
!$request->user($guard)->hasVerifiedEmail())
) {
return $request->expectsJson()
? abort(403, 'Your email address is not verified.')
: Redirect::route($redirectToRoute ?: 'verification.notice');
}
return $next($request);
}
}
protected $routeMiddleware = [
-------------------------------------
// 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'verified' => \App\Http\Middleware\EnsureEmailIsVerified::class,
];
4.middleware('password.confirm)
引数にリダイレクトルートを設定するだけで修正する必要がない。
})->middleware(['auth:admin-web', 'password.confirm:admin.password.confirm']);
Admin authのviewsのリンクの宛先を修正する。
新たにルートを追加する
Route::group(['prefix' => '/admin', 'namespace' => 'Admin', 'as' => 'admin.'], function () {
//+
Route::get('/', function () {
return view('admin.welcome');
})->name('welcome');
Auth::routes(['verify' => true]);
//+
Route::get('/home', [App\Http\Controllers\Admin\HomeController::class, 'index'])->name('home');
});
//検索
@extends('layouts.app
//置換
@extends('layouts.admin_app
//検索
route('
//置換
route('admin.
@if (Route::has('login'))
{{-- @if (Route::has('login'))の中を置き換え--}}
<div class="hidden fixed top-0 right-0 px-6 py-4 sm:block">
@auth('admin-web')
<a href="{{ url('/admin/home') }}" class="text-sm text-gray-700 underline">Home</a>
@else
<a href="{{ route('admin.login') }}" class="text-sm text-gray-700 underline">Log in</a>
@if (Route::has('register'))
<a href="{{ route('admin.register') }}" class="ml-4 text-sm text-gray-700 underline">Register</a>
@endif
@endauth
<a href="{{ url('/') }}" class="text-sm text-gray-700 underline" style="margin-left: 15px">User</a>
</div>
@endif
//検索
@guest
//置換
@guest('admin-web')
//検索
route('
//置換
route('admin.
ついでに、adminのリンクを追記
-----
@auth
省略
@endauth
//追記
<a href="{{ url('/admin') }}" class="text-sm text-gray-700 underline" style="margin-left: 15px">Admin</a>
Adminユーザーの機能を確認する。
- ログイン機能
- パスワードのリセット機能
- Email Verification機能(登録されたメールの確認機能)
- メールの実在性の確認
- ログインかつメール認証済みのユーザだけを許可する認証ができる。
- password confirm機能(再度passwordの再確認を求める)
上記機能を確認するためのルートを作成する
//uri,コントローラー,nameの重複を解消
Route::group(['prefix' => '/admin', 'namespace' => 'Admin', 'as' => 'admin.'], function () {
Route::get('/', function () {
return view('admin.welcome');
})->name('welcome');
Auth::routes(['verify' => true]);
Route::get('/home', [App\Http\Controllers\Admin\HomeController::class, 'index'])->name('home');
//+
//検証確認済みしかアクセスできないルート
Route::get('/verified', function () {
return 'あなたのメールは検証済みです。';
})->middleware(['auth:admin-web','verified:admin.verification.notice,admin-web']);
//パスワードの再確認がいるルート
Route::get('/confirmed', function () {
return 'パスワードが確認できました';
})->middleware(['auth:admin-web', 'password.confirm:admin.password.confirm']);
});
route('admin.welcome')にアクセスすると、リンクが作成されている。
adminユーザー登録するとデータがadminsテーブルに登録される。
ログインしてミドルウェアを確認する。
route('admin.login')にアクセスする。
route('admin.home')に遷移される。
ログアウトするとroute('admin.welcome')に遷移される。
ログアウト中にroute('admin.home')へアクセスすると
route('admin.login')に遷移される。
route('admin.verified')にアクセスする
ログインアウト中ならroute('admin.login')に遷移
ログイン中+未検証なら。route('admin.email')に遷移される。
メールにアクセスするとroute('admin.verified')にアクセスできた。
middleware('verified:admin.verification.notice,admin-web')の
リダイレクト先を遷移前のルートに変更する。
デフォルトではログイン後route('admin.home');に遷移される。
public function handle($request, Closure $next, $redirectToRoute = null, $guard = null)
{
if (
!$request->user($guard) ||
($request->user($guard) instanceof MustVerifyEmail &&
!$request->user($guard)->hasVerifiedEmail())
) {
//+
//追記 Session::pull('url.intended');コレが使えない(T_T)ためこんなことしてる。
$path = $request->url();//追記
session(['verified' => $path]);//追記
return $request->expectsJson()
? abort(403, 'Your email address is not verified.')
: Redirect::route($redirectToRoute ?: 'verification.notice');
}
return $next($request);
}
//ログイン後の遷移先
//+
public function redirectPath()
{
session()->forget('url.intended');
$path = session()->pull('verified');
return $path;
}
webとadmin-webの情報を取得する場合
{{ dd(auth('web')->user(),auth('admin-web')->user()) }}
@Auth
Laravel メールをキューを使って送信する
①Userモデルのpasswordリセット、verificationメール
②Adminモデルのpasswordリセット、verificationメール
それぞれで実装する。
Userモデルのpasswordリセット、verificationメールをキュ~送信する。
envファイルでの設定。
QUEUE_CONNECTION=database
//queue送信時routeの生成で利用するため。
APP_URL=https://localhost/user_admin_auth/public
jobsテーブルのマイグレーションファイルを作成
php artisan queue:table
テーブルを作成する。
php artisan migrate
1.Userのメール送信をqueu送信する。
verificationメールをqueu送信.
メール機能を拡張する必要があるため、メールを作る
php artisan make:notification UserVerifyEmailNotification
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Notifications\VerifyEmail;//追記
class UserVerifyEmailNotification /*<修正>*/extends VerifyEmail implements ShouldQueue /*</修正>*/
{
use Queueable;
//以下削除
}
use App\Notifications\UserVerifyEmailNotification;//追記
------------
//追記
public function sendEmailVerificationNotification()
{
$this->notify(new UserVerifyEmailNotification());
}
passwordリセットをqueu送信する
手順は全く同じ。
php artisan make:notification UserResetPasswordEmailNotification
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Auth\Notifications\ResetPassword;
class UserResetPasswordEmailNotification /*<修正>*/extends ResetPassword implements ShouldQueue/*</修正>*/
{
use Queueable;
}
public function sendPasswordResetNotification($token)
{
//引数は要,トークンとルート名とpasswords名
$this->notify(new UserResetPasswordEmailNotification($token, 'password.reset', 'users'));
}
php artisan queu:work
設定を確認する。
未検証のメールで登録して、動作が改善されているのを確認して送られてきたメールのリンクをクリックして検証を完了させる。
パスワードリセットにメールを送って、動作が改善されているのを確認して送られてきたメールのリンクをクリックしてパスワードをリセットする。
Adminのメールをqueu送信する。
これは既にメールを作成済みなので作成済みメールを修正する。
Adminのverificationメールをqueu送信.
use Illuminate\Contracts\Queue\ShouldQueue;//無ければ追加
class VerifyEmailNotification extends VerifyEmail /*<追記>*/implements ShouldQueue/*</追記>*/
{
use Queueable;//コメントアウトしてたら解除
AdminのpasswordResetメールをqueu送信.
use Illuminate\Contracts\Queue\ShouldQueue;//無ければ追加
class ResetPasswordNotification extends ResetPassword /*<追記>*/implements ShouldQueue/*</追記>*/
{
use Queueable;//コメントアウトしてたら解除
一般ログインと管理ログインを同時にしている状態を防ぐ
user
の ログインコントローラに、
public function __construct()
{
// web 認証していると logout メソッド以外のメソッドにはアクセスできなくなる。
$this->middleware('guest')->except('logout');
// admin-web認証していると 全てのメソッドへのアクセスを拒否される。
$this->middleware('guest:admin-web');
}
管理画面のルートとuser画面のルートでファイルを区分
-
RouteServiceProvider.php
でadminルートとuserルートを別々のファイルで管理させる。- 一般ユーザー用の
front.php
、 - 管理画面用の
back.php
- 一般ユーザー用の
public const HOME = '/home';
//追記
protected $namespace = 'App\Http\Controllers';
//追記
public const ADMIN_HOME = '/admin/home';
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
//コメントアウト
// Route::middleware('web')
// ->namespace($this->namespace)
// ->group(base_path('routes/web.php'));
// フロント画面 routes/front.php
Route::middleware('web')
->namespace($this->namespace . '\Front')
->as('front.')
//filepath+file名
->group(base_path('routes/front.php'));
// 管理画面 routes/back.php
//admin/~
Route::prefix('admin')
->middleware('web')
//コントローラーのエイリアスを指定
->namespace($this->namespace . '\Back')
->as('back.')
//filepath+file名
->group(base_path('routes/back.php'));
});
}
ルートでのコントローラーのエイリアスを省略したい場合は下記のコードを追加するだけでいい。
//追記
protected $namespace = 'App\Http\Controllers';
ログインに必要な項目を変更する
- email から name に変更
// +
public function username()
{
// return 'email';
return 'name';
}
ログインに必要な項目を追加する
簡単な方から。
active項目が1である条件を付加している。らしぃ。
リクエストでactive
を送信してusers
テーブルからuserを取得できたらtrue
になる。
//credentials()をオーバーライド
protected function credentials(Request $request)
{
$request->merge(['active' => 1]);
return $request->only($this->username(), 'password', 'active');
}
- 解説
- SessionGuardインスタンスのattemptメソッド
// credentialsは['email'=>'xxx','password'=>'xxx','active'=>1]
public function attempt(array $credentials = [], $remember = false)
{
$this->fireAttemptEvent($credentials, $remember);
// ここで DB から (emailとactive の値 が一致する) user を 取得 する。
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// 取得したuser の パスワードをチェックしてOKだったら
if ($this->hasValidCredentials($user, $credentials)) {
// ログインして true を返す
$this->login($user, $remember);
return true;
}
// パスワードチェックがfalseだったら false を 返す
return false;
}
複数テーブルを参照する等、少し複雑な認証をしたい場合
その他参照サイト