初心者でもLaravelのユーザー認証が使えるようになる解説

Featured image of the post

概要

Authについて一週間かけて一から学習した。

同じ初心者でも理解できるよう学んだことをすべて備忘録に残す。

Laravelにおけるユーザー認証
  • ユーザー認証とはログイン機能のこと✅
  • 一から作ると大変だがLaravelではAuthクラスが用意されており簡単に実装できる✅

【補足】他の実装方法

💡
ここでは初心者でもAuthが使えるよう丁寧に解説する。
  • 導入方法
  • よくある画面の作り方
  • 知ってると便利なカスタマイズ機能

導入方法

前提
  • Laravel6以降の実装方法を紹介する。
  • Node.jsがインストールされている必要がある。

【ステップ1】laravel/uiをインストールする

以下のコマンドを実行する✅

composer require laravel/ui

【ステップ2】Authで使うファイルを生成する

以下のコマンドを順番に実行する✅

php artisan ui vue --auth
npm install && npm run dev

【ステップ3】マイグレーションを実行する

以下のコマンドを実行する✅

php artisan migrate

💡
これだけでユーザー認証に使うものがすべて揃う!

導入後の解説

usersテーブル
  • データベースにusersテーブルができている。
Image in a image block

💡
ユーザー情報を格納する

password_resetsテーブル
  • データベースにpassword_resetsテーブルができている。
Image in a image block

💡
パスワードリセット機能で使用する

モデル
  • usersテーブルで使うモデルクラス。
app/Models/User.php
<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

// ※通常のモデルとは異なりAuthenticatableを継承している✅
class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

💡
ユーザー認証で使用する

ログイン関連のページ
ファイル名 説明 URL
resources/views/auth/
login.blade.php
ログインページ ドメイン名/login
resources/views/auth/
register.blade.php
新規ユーザー登録ページ ドメイン名/register
resources/views/auth/
verify.blade.php
メール認証ページ ドメイン名/verify
resources/views/auth/passwords/
confirm.blade.php
パスワード認証 ドメイン名/password/confirm
resources/views/auth/passwords/
email.blade.php
パスワード再設定(メアド入力画面) ドメイン名/password/email
resources/views/auth/passwords/
reset.blade.php
パスワード再設定(再設定画面) ドメイン名/password/reset
resources/views/home.blade.php ホーム画面 ドメイン名/home

💡
ユーザー認証で必要最低限のページは全部用意してくれる

ルーティング
  • 以下のルーティングが追加されている。
routes/web.php
// ログイン関連のページのルーティング
// これ1行で全ページ(ホーム画面以外)のルーティングが完了する
Auth::routes();

// ログインのホーム画面のルーティング
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');

💡
すぐにユーザー認証が使えるよう設定されている

コントローラー
ファイル名 説明
app/Http/Controllers/Auth/
LoginController.php
ログインページのコントローラー
app/Http/Controllers/Auth/
RegisterController.php
新規ユーザー登録ページのコントローラー
app/Http/Controllers/Auth/
VerificationController.php
メール認証ページのコントローラー
app/Http/Controllers/Auth/
ConfirmPasswordController.php
パスワード認証ページのコントローラー
app/Http/Controllers/Auth/
ForgotPasswordController.php
パスワードを忘れた場合に、パスワード再設定のためのメール送信を行うコントローラー
app/Http/Controllers/Auth/
ResetPasswordController.php
パスワード再設定用のページを表示し、パスワードの変更を行うコントローラー 
app/Http/Controllers/HomeController.php ホーム画面のコントローラー

ログイン機能を使ってみる

ユーザー新規登録

/registerにアクセスすると登録画面が表示される。

Image in a image block

適当に入力して「Register」をクリックすると、ユーザー登録とログインが完了する✅

Image in a image block

💡
登録したデータはusersテーブルに保存されている

ログアウト

右上のユーザー名をクリック→Logout

Image in a image block

💡
ログアウト後はトップページに移動する

ログイン

/loginにアクセスするとログイン画面が表示される

Image in a image block

登録したメールアドレスとパスワードを入力して「Login」をクリックすると、ログインが完了する✅

Image in a image block

💡
デフォルトでは「メールアドレス」「パスワード」でログインする

会員機能を一通り作成してみる

【前提】必要な画面

よく実装される画面✅

画面 補足
会員登録ページ メール認証機能を付ける!
ログインページ
ログアウトページ ログイン状態でのみアクセス可
マイページ ログイン状態でのみアクセス可
退会ページ ログイン状態でのみアクセス可
ユーザー情報変更ページ ログイン状態でのみアクセス可
パスワードリセットページ

💡
必須ではないがこれくらいの画面はほしい…!

会員登録ページ
  • デフォルトの会員登録ページを使う✅
  • 何もしなくてOK
コントローラー app/Http/Controllers/Auth/RegisterController.php
ビュー resources/views/auth/register.blade.php
URL ドメイン名/register

ドメイン名/register

Image in a image block

💡
項目を増やしたい場合は後述の「会員登録の入力項目を増やす」を参照。

会員登録ページ(メール認証機能)
  • デフォルトの認証機能を使う✅
  • 有効化が必要!
コントローラー app/Http/Controllers/Auth/VerificationController.php
ビュー resources/views/auth/verify.blade.php
URL ドメイン名/verify

メール認証とは

メール認証とは、会員登録でよくある以下の流れのこと。

  1. 会員登録ページで「名前」「メールアドレス」「パスワード」などを入力
  2. 入力されたメールアドレス宛に確認メールを送信
  3. メールの中の確認用リンクを踏んでもらう
  4. メール認証完了

Laravelではデフォルトでメール認証が用意されている!

ただし使うには有効化する必要がある

メール認証の実装方法
【ステップ1】メール送信の設定

そもそもメールを送信するには事前に設定が必要!

💡
以下の「準備」が参考になる。

【ステップ2】メール認証の有効化

元々備わっている機能を有効化するだけなので簡単🔰

2ステップでOK!

  • モデルを修正する

    app/Models/User.php

    // メール認証を使うため「implements MustVerifyEmail」を付ける
    class User extends Authenticatable implements MustVerifyEmail
    {
        ...
    }

  • ルーティングを修正する

    routes/web.php

    // メール認証を使うため引数を増やす
    Auth::routes(['verify' => true]);

💡
これだけでメール認証が有効化される!

【補足】メール認証済みかどうかはどうやって判断している?

usersテーブルのemail_verified_atで判断している✅

→認証完了した日時が格納されている。

動作確認

ここまで設定できたら、ユーザー登録時に確認メールが送信されるようになっている✅

ドメイン名/registerにアクセスしユーザー登録する。

Image in a image block

自動でログイン完了画面に遷移する。

(メール認証しなくてもアカウント作成は完了する)

Image in a image block

このとき以下のような確認メールが届いているはず!

URLをクリックすると認証が完了する✅

Image in a image block

メール認証後のリダイレクト先を変える

デフォルトでは認証後、ドメイン名/homeにリダイレクトされる。

これを別のページに変えるのは簡単!

  • $redirectToを変更するだけ✅

    app/Http/Controllers/Auth/VerificationController.php

    class VerificationController extends Controller
    {
    		// 例:ドメイン名/hoge にリダイレクトする
    		protected $redirectTo = '/hoge';
    }

メール認証していないユーザーにアクセス制限をかける

メール認証を有効化するだけでは、ユーザー登録時に認証メールが送られるだけ。

💡
「このページはメール認証してないと見れないよ!」の設定をして初めて意味がある。

  • ルーティングで->middleware('verified')を設定するだけでOK✅

    routes/web.php

    // 任意のルーティングに ->middleware('verified') を付け足す!
    // →「ドメイン名/hoge」にアクセス制限がかかる!
    Route::get('/hoge', 'App\Http\Controllers\TestController@hoge')->middleware('verified');

【補足】ログイン制限とメール認証制限の違い

メール認証の方が厳しい制限。

どちらか片方を指定すればOK!

種類 ログインの有無 メール認証の有無
ログイン制限
メール認証制限

💡
これだけでアクセス制限がかかる。
メール認証していないときはログインページにリダイレクトしてくれる!

メール認証していないユーザーにアクセス制限をかける(全ページ)

前述の方法では1ページずつアクセス制限をかけないといけない😫

特定のコントローラーのページすべてにアクセス制限をかけることができる!

  • コンストラクタで$this->middleware('verified')を設定するだけでOK✅

    例:app/Http/Controllers/TestController.php

    class TestController extends Controller
    {
    		public function __construct()
        {
            // アクセス制限
            // ただしindex, show, topは除く
            $this->middleware('verified')->except(['index', 'show', 'top']);
        }
    }

💡
except(…)で対象外のページを指定することもできる!
→引数はアクションメソッド名

ログインページ
  • デフォルトのログインページを使う✅
  • 何もしなくてOK
コントローラー app/Http/Controllers/Auth/LoginController.php
ビュー resources/views/auth/login.blade.php
URL ドメイン名/login

ドメイン名/login

Image in a image block

💡
項目を増やしたい場合は後述の「ログインの入力項目を増やす」を参照。
💡
ログイン後の遷移先を変えたい場合は後述「ログイン後のリダイレクト先を変更する」を参照。

ログアウト
  • デフォルトのログアウト機能を使う✅
  • 何もしなくてOK

ドメイン名/home など

Image in a image block

【補足】他のページにログアウトを実装する方法(例と同じデザイン)
上記の例と同じでヘッダーにログアウト機能を付ける

resources/views/home.blade.phpを真似して@extends('layouts.app')を使う✅

【補足】他のページにログアウトを実装する方法(自作ボタン)
任意の位置にログアウトボタンを作る
  • URLドメイン名/routeにPOST送信するだけでログアウトできる。

以下のログアウトボタンでログアウトできる!

<a class="dropdown-item" href="{{ route('logout') }}"
    onclick="event.preventDefault();
                    document.getElementById('logout-form').submit();">
    {{ __('Logout') }}
</a>

<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
    @csrf
</form>

💡
上記は resources/views/layouts/app.blade.php のコピペ。
aタグを使わずformタグだけで実装してもOK!

💡
ログアウト後の遷移先を変えたい場合は後述「ログアウト後のリダイレクト先を変更する」を参照。

マイページ
  • 会員データを表示するページを自作する✅

💡
今回は「名前」「メールアドレス」「登録日」「更新日」を表示する。

完成イメージ

CSSなしで、とりあえずデータを表示することだけ考える。

Image in a image block

ルーティング

マイページのルーティングを設定する。

routes/web.php

// マイページ
Route::get('/myPage', 'App\Http\Controllers\TestController@myPage')->name('myPage')->middleware('verified');

  • コントローラーは何でもOK✅
  • middleware('verified')はメール認証していないとアクセス不可という意味✅

コントローラー

マイページを表示するアクションメソッドを追加する。

app/Http/Controllers/TestController.php

class TestController extends Controller
{
		// マイページ
    public function myPage(){
				// ログイン中のユーザーを取得
        $user = Auth::user();
				// ビューを表示
        return view('myPage', compact('user'));
    }
}

  • Auth::user()でログイン中のユーザーを取得できる✅

ビュー

マイページのビューを作成する。

resources/views/myPage.blade.php(新規作成)

<h1>マイページ</h1>
<dl>
    <dt>名前</dt>
    <dd>{{ $user->name }}</dd>
    <dt>メールアドレス</dt>
    <dd>{{ $user->email }}</dd>
    <dt>登録日</dt>
    <dd>{{ $user->created_at }}</dd>
    <dt>更新日</dt>
    <dd>{{ $user->updated_at }}</dd>
</dl>

  • コントローラーからもらった$userを使ってデータを表示する✅
  • $userはモデル(App\Models\User)なので->カラム名で取得できる。

Image in a image block

💡
意外と簡単!

退会ページ
  • 会員データを削除するページを自作する✅

💡
今回は論理削除で実装する。

完成イメージ

CSSなしで、とりあえず退会を実装することだけ考える。

退会画面

Image in a image block

「退会する」をクリックすると…

Image in a image block

usersテーブルにカラムを増やす

マイグレーションファイルを作成する。

以下のコマンドを実行すればOK✅

php artisan make:migration add_softDeletes_to_users_table

自動生成されたマイグレーションファイルを編集する✅

例:database/migrations/2023_03_26_091121_add_column_to_users_table.php など

<?php
class AddSoftDeletesToUsersTable extends Migration
{
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            // ①項目を追加
						$table->softDeletes();  // 論理削除フラグ
        });
    }

    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            // ②項目を追加
            $table->dropColumn('deleted_at');   // 論理削除フラグ
        });
    }
}

マイグレーションコマンドを実行する✅

php artisan migrate

💡
これでusersテーブルに「deleted_at」が追加された

🚫 ただいま記事作成中です💭

モデルを修正
  • モデルが論理削除フラグを扱えるようにする✅

app/Models/User.php

// ①追記
use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Authenticatable
{
		// ②論理削除を使う
    use SoftDeletes;
    // ③日付型として扱う
    protected $dates = ['deleted_at'];
}

💡
データベース周りの対応はこれでOK

ルーティング

退会ページのルーティングを設定する。

routes/web.php

// 退会ページ(退会画面)
Route::get('/userDelete', 'App\Http\Controllers\TestController@userDelete')->name('userDelete')->middleware('verified');
// 退会ページ(退会処理)
Route::delete('/userDelete', 'App\Http\Controllers\TestController@destroyUserDelete')->name('destroyUserDelete')->middleware('verified');
// 退会ページ(退会完了画面)
Route::get('/userDeleteComplete', 'App\Http\Controllers\TestController@userDeleteComplete')->name('userDeleteComplete');

  • コントローラーは何でもOK✅
  • middleware('verified')はメール認証していないとアクセス不可という意味✅

コントローラー

退会するためのアクションメソッドを追加する。

app/Http/Controllers/TestController.php

class TestController extends Controller
{
		// ①退会ページ(退会画面)
    public function userDelete(){
        return view('userDelete');
    }

    // ②退会ページ(退会処理)
    public function destroyUserDelete(){
        // 現在ログインしているユーザーを取得
        $user = Auth::user();
        // 論理削除
        $user->delete();
        // 退会完了ページへリダイレクト
        return redirect()->route('userDeleteComplete');
    }

    // ③退会ページ(退会完了画面)
    public function userDeleteComplete(){
        return view('userDeleteComplete');
    }
}

  • ②の退会処理が重要!
  • delete()で論理削除(退会)することができる✅

💡
これだけでユーザーは退会したことになる!

ビュー(退会画面)

退会画面のビューを作成する。

resources/views/userDelete.blade.php(新規作成)

<h1>退会しますか?</h1>
<form method="post" action="{{ route('destroyUserDelete') }}">
    @csrf
    @method('delete')
    <input type="submit" value="退会する">
</form>

  • 退会するフォームを設置するだけ✅
  • ルーティングの際にHTTPメソッドはdeleteにしていたので@method('delete')を指定しておく。

Image in a image block

ビュー(退会完了画面)

退会完了画面のビューを作成する。

resources/views/userDelete.blade.php(新規作成)

<h1>退会が完了しました。</h1>

Image in a image block

同じメールアドレスで再登録できるようにする
  • メールアドレスの重複NG!
  • 論理削除したデータは内部に残っているので同じメールアドレスで再登録できない🥲

アカウント新規作成時に古いデータを物理削除する

app/Http/Controllers/Auth/RegisterController.php

class RegisterController extends Controller
{
    protected function validator(array $data)
    {
				// 以下を追加!
        // 過去に論理削除されたメールアドレスで再登録しようとしたとき
        $user = User::where('email', $data['email'])->withTrashed()->first();
        if ($user && $user->deleted_at !== null) {
            // 過去のデータを物理削除
            $user->forceDelete();
        }

				// 変更なし
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }
}

💡
先に古いデータを物理削除しておくことで、メールアドレスが重複せずに再登録できる!

ユーザー情報変更ページ
  • 会員データを編集する画面を自作する✅

    (マイページと似ている)

💡
今回は「名前」「メールアドレス」を更新する。

完成イメージ

CSSなしで、とりあえずデータを表示することだけ考える。

Image in a image block

「更新する」をクリックして更新に成功すると…

Image in a image block

「更新する」をクリックして更新に失敗すると…

Image in a image block

ルーティング

ユーザー情報変更ページのルーティングを設定する。

routes/web.php

// ユーザー情報変更ページ(編集画面)
Route::get('/myEdit', 'App\Http\Controllers\TestController@myEdit')->name('myEdit')->middleware('verified');
// ユーザー情報変更ページ(更新処理)
Route::put('/myEdit', 'App\Http\Controllers\TestController@putMyEdit')->name('putMyEdit')->middleware('verified');

  • コントローラーは何でもOK✅
  • middleware('verified')はメール認証していないとアクセス不可という意味✅

コントローラー

ユーザー情報を変更するアクションメソッドを追加する。

app/Http/Controllers/TestController.php

class TestController extends Controller
{
		// ①ユーザー情報変更ページ(編集画面)
    public function myEdit(){
				// ログイン中のユーザーを取得
        $user = Auth::user();
				// ビューを表示
        return view('myEdit', compact('user'));
    }

    // ②ユーザー情報変更ページ(更新処理)
    public function putMyEdit( Request $request ){
        // バリデーションを実行し、合格した入力データを取得(基本的には新規登録のバリデーションと同じルールにする)
        $inputs = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255',
                Rule::unique('users')->ignore(Auth::id()), // 自分のIDは重複チェックから除外する
            ],
        ]);

        // ユーザー情報を更新
        Auth::user()->update($inputs);

        // 編集ページへリダイレクト
        $message = '更新に成功しました。';
        return redirect()->route('myEdit')->with(compact('message'));
    }
}

  • 編集画面はマイページと同じ✅
  • 更新処理は バリデーション → 更新 の流れ✅

    メールアドレスの重複チェックは、他人との重複NG、自分との重複OKとしている。

【補足】メール認証を有効化している場合

メールアドレスを変更するときに、再度メール認証をする必要がある✅

(認証しないと架空のメールアドレスが設定されてしまう)

以下で詳しく解説されている。

💡
これだけで更新処理はOK!

ビュー

編集画面のビューを作成する。

resources/views/myEdit.blade.php(新規作成)

<h1>ユーザー情報変更</h1>
{{-- バリデーションエラーあり --}}
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

{{-- 更新成功メッセージ --}}
@if (session('message'))
<div>
    {{ session('message') }}
</div>
@endif

<form method="post" action="{{ route('myEdit') }}">
    @csrf
    @method('put')
    <div>
        <label for="name">名前</label>
        <input type="text" id="name" name="name" value="{{ old('name', $user->name) }}" />
    </div>

    <div>
        <label for="email">メールアドレス</label>
        <input type="email" id="email" name="email" value="{{ old('email', $user->email) }}" />
    </div>

    <input type="submit" value="更新する">
</form>

  • コントローラーからもらった$userを使って編集前のデータを表示する
  • ルーティングの際にHTTPメソッドはputにしていたので@method('put')を指定しておく。

更新成功したとき(成功メッセージ)

Image in a image block

更新失敗したとき(バリデーションエラー)

Image in a image block

パスワード初期化ページ
  • デフォルトの初期化機能を使う✅
  • 何もしなくてOK
コントローラー app/Http/Controllers/Auth/ResetPasswordController.php
ビュー resources/views/auth/passwords/reset.blade.php
URL ドメイン名/password/reset

💡
パスワードを忘れたときに使う機能

動作確認

ドメイン名/password/resetにアクセスしメールアドレスを入力する。

(ログイン画面の "Forgot Your Password?” をクリックするとこのページにくる)

Image in a image block

「We have emailed your password reset link!」と表示される。

Image in a image block

このとき以下のような初期化メールが届いているはず!

URLをクリックすると初期化ページに移動する。

Image in a image block

新しいパスワードを入力し「Reset Password」をクリックする。

Image in a image block

「Your password has been reset!」と表示され、再設定が完了する

Image in a image block

カスタマイズで使える知識

ログイン中か判定

「通常のPHP」と「blade」で2種類の方法が用意されている。

コントローラーなど(phpファイル)の場合
  • Auth::check();を使う✅

if ( Auth::check() ) 
{
	// ログイン中の場合
}
else
{
	// 未ログインの場合
}

ビュー(bladeファイル)の場合
  • @auth〜@endauth@guest @endguestを使う✅

@auth
	{{-- ログイン中の場合 --}}
@endauth

@guest
	{{-- 未ログインの場合 --}}
@endguest

💡
bladeはディレクティブが用意されている!

ログイン中のユーザー情報を取得する
ユーザーデータを全部取得する
  • Auth::user();を使う✅

例:app/Http/Controllers/TestController.php

// ①追記
use Illuminate\Support\Facades\Auth;

class TestController extends Controller
{
    public function hoge()
    {
				// ②ログイン中のユーザーを取得
        $user = Auth::user();

				// ③データを取得
				$id = $user->id;
				$name = $user->name;

				// ④ビューにユーザー情報を渡す
        return view('hoge', compact('id','name'));

				// ④もしくは$userを丸ごと渡してもいい
				// return view('hoge', compact('user'));
    }
}

【補足】戻り値について
  • Auth::user();の戻り値はモデル(UserクラスApp\Models\User
  • そのため通常のモデルと同じく値の取得が簡単!

    $user->idなどで取得できる

dd($user);の結果

Image in a image block

【補足】戻り値の型

厳密にはAuthenticatableインターフェイスと定義されているがデフォルトではUserクラスApp\Models\Userが返ってくる。

最初は気にする必要なし!

IDだけ取得する
  • Auth::id()を使う✅

例:app/Http/Controllers/TestController.php

// ①追記
use Illuminate\Support\Facades\Auth;

class TestController extends Controller
{
    public function hoge()
    {
				// ②ログイン中のユーザーのIDを取得
        $id = Auth::id();

				// ③ビューにユーザーのIDを渡す
        return view('hoge', compact('id'));
    }
}

ログインする
  • Auth::attempt();を使う✅
    • メールアドレスとパスワードが一致すればログインできる。

例:app/Http/Controllers/TestController.php

// ①追記
use Illuminate\Support\Facades\Auth;

class TestController extends Controller
{
    public function hoge()
    {
				// ②ログイン処理
				$bLogin = Auth::attempt( array(
			    'email' => 'aaa@test.com',     // メールアドレス
			    'password' => '12345678',      // パスワード
				));

				if ( bLogin ){
					// ログイン成功時の処理
				}
				else{
					// ログイン失敗時の処理
				}

        return view('hoge');
    }
}

💡
デフォルトで用意されているログインページ/login以外でもログイン機能が実装できる

ログイン後のリダイレクト先を変更する
  • デフォルトのログアウト処理(/login)を使うと、自動的に/homeにリダイレクトされる。

/home

Image in a image block

→ログインすると/homeにいく

  • このリダイレクト先を別ページに設定する方法✅
  • コントローラーの$redirectToを書き換えるだけでOK

    app/Http/Controllers/Auth/LoginController.php

    class LoginController extends Controller
    {
    		// ログイン後「ドメイン名/hoge」に遷移する
        protected $redirectTo = '/hoge';
    }

💡
変更が効かない場合はブラウザのキャッシュをクリアするといい

【補足】ログイン後、元いたページに戻す方法

コントローラーにメソッドを追加するだけでOK!

app/Http/Controllers/Auth/LoginController.php

class LoginController extends Controller
{
    // 追記
    public function showLoginForm()
    {
        if (!session()->has('url.intended')) {
            session(['url.intended' => url()->previous()]);
        }
        return view('auth.login');
    }
}

参考

ログアウトする
  • Auth::logout();を使う✅

例:app/Http/Controllers/TestController.php

// ①追記
use Illuminate\Support\Facades\Auth;

class TestController extends Controller
{
    public function hoge()
    {
				// ②ログアウト処理
				$bLogin = Auth::logout();

        return view('hoge');
    }
}

💡
デフォルトで用意されているログアウトページ/logout以外でもログアウト機能が実装できる

ログアウト後のリダイレクト先を変更する
  • デフォルトのログアウト処理(/logout)を使うと、自動的にトップページにリダイレクトされる。
Image in a image block

→ログアウトするとトップページにいく

  • このリダイレクト先をトップページ以外に設定する方法✅
  • コントローラーにメソッドを追加するだけでOK

    app/Http/Controllers/Auth/LoginController.php

    class LoginController extends Controller
    {
    		// ログアウト後「ドメイン名/hoge」に遷移する
    		protected function loggedOut()
        {
            return redirect('/hoge');
        }
    }

💡
変更が効かない場合はブラウザのキャッシュをクリアするといい

各ページのデザインを変える

ビューを編集するだけ✅

以下のファイルを好きなように修正する。

ファイル名 説明 URL
resources/views/auth/
login.blade.php
ログインページ ドメイン名/login
resources/views/auth/
register.blade.php
新規ユーザー登録ページ ドメイン名/register
resources/views/auth/
verify.blade.php
メール認証ページ ドメイン名/verify
resources/views/auth/passwords/
confirm.blade.php
パスワード認証 ドメイン名/password/confirm
resources/views/auth/passwords/
email.blade.php
パスワード再設定(メアド入力画面) ドメイン名/password/email
resources/views/auth/passwords/
reset.blade.php
パスワード再設定(再設定画面) ドメイン名/password/reset
resources/views/home.blade.php ホーム画面 ドメイン名/home

ログイン制限をかける

ログインしないとアクセスできないようにする方法

  • ルーティングにミドルウェアを設定するだけ✅
    • ミドルウェアを知らなくても簡単に使える。
    • 具体的には->middleware('auth')と書くだけでOK✅

routes/web.php

// 任意のルーティングに ->middleware('auth') を付け足す!
// →「ドメイン名/hoge」にアクセス制限がかかる!
Route::get('/hoge', 'App\Http\Controllers\TestController@hoge')->middleware('auth');

【補足】未ログイン制限をかける

反対にゲストユーザーのみアクセス可能にすることもできる✅

「新規登録画面」などで有用!

routes/web.php

// 任意のルーティングに ->middleware('guest') を付け足す!
// →「ドメイン名/hoge」にアクセス制限がかかる!
Route::get('/hoge', 'App\Http\Controllers\TestController@hoge')->middleware('guest');

💡
これだけでログイン制限がかかる。
未ログインのときはログインページにリダイレクトしてくれる!

ログイン制限をかける(全ページ)

前述の方法では1ページずつログイン制限をかけないといけない😫

特定のコントローラーのページすべてにログイン制限をかけることができる!

  • コンストラクタで$this->middleware('auth')を設定するだけでOK✅

    例:app/Http/Controllers/TestController.php

    class TestController extends Controller
    {
    		public function __construct()
        {
            // アクセス制限
            // ただしindex, show, topは除く
            $this->middleware('auth')->except(['index', 'show', 'top']);
        }
    }

💡
except(…)で対象外のページを指定することもできる!
→引数はアクションメソッド名

会員登録の入力項目を増やす

任意の会員登録画面を作る方法は2つある

  • デフォルトの会員登録画面をカスタマイズする✅

    一般的な会員機能ならカスタマイズで十分対応できる(?)

  • 新しく会員登録画面を作る✅

    特殊な要件のときは新しく会員登録画面を作る(?)

    https://www.petitmonte.com/php/laravel_original_login.html

💡
ここではデフォルトの会員登録画面に以下を追加する。
・電話番号(必須)
・ニックネーム(任意)

完成イメージ
Image in a image block

usersテーブルにカラムを増やす

マイグレーションファイルを作成する。

以下のコマンドを実行すればOK✅

php artisan make:migration add_column_to_users_table

自動生成されたマイグレーションファイルを編集する✅

例:database/migrations/2023_03_26_091121_add_column_to_users_table.php など

<?php
class AddColumnToUsersTable extends Migration
{
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            // ①項目を追加
            $table->string('tel',11);               // 電話番号
            $table->string('nickname')->nullable(); // ニックネーム(任意)
                                                    // ※任意なのでnullable()を付けておく。
        });
    }

    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            // ②項目を追加
            $table->dropColumn('tel');       // 電話番号
            $table->dropColumn('nickname');  // ニックネーム
        });
    }
}

マイグレーションコマンドを実行する✅

php artisan migrate

【注意】すでにレコードがある場合はマイグレーションエラーになる

上記のマイグレーションは「NULL禁止」かつ「デフォルト値が未設定」⚠️

カラムが増えたときに既存レコードはこの問題を解決できないためエラーになる🥲

解決方法は以下を参照

💡
これでusersテーブルに「tel」「nickname」が追加された

🚫 ただいま記事作成中です💭

モデルを修正
  • モデルが電話番号とニックネームを扱えるようにする✅

app/Models/User.php

class User extends Authenticatable
{
    protected $fillable = [
        'name',
        'email',
        'password',

        // 追加
        'tel',      // 電話番号
        'nickname', // ニックネーム
    ];
}

💡
データベース周りの対応はこれでOK

コントローラーを修正
  • バリデーションを追加する✅
  • 登録する項目を追加する✅

app/Http/Controllers/Auth/RegisterController.php

class RegisterController extends Controller
{
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],

						// ①バリデーション追加
            'tel' => ['required', 'string', 'max:11'],       // 電話番号(必須、文字列、11文字まで)
						'nickname' => ['nullable', 'string', 'max:255'], // ニックネーム(任意、文字列、255文字まで)
                                                             // ※必須入力ではないので'nullable'を付けておく
        ]);
    }

    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),

            // ②登録する項目を追加
            'tel' => $data['tel'],              // 電話番号
            'nickname' => $data['nickname'],    // ニックネーム
        ]);
    }
}

💡
これで登録処理はOK

ビューを修正
  • 画面に入力項目を追加する✅
    • <form>〜</form>の中に追加する。
    • 他の入力項目を真似すればOK。

resources/views/auth/register.blade.php

{{-- 電話番号 --}}
<div class="row mb-3">
    <label for="tel" class="col-md-4 col-form-label text-md-end">tel</label>

    <div class="col-md-6">
        <input id="tel" type="text" class="form-control @error('tel') is-invalid @enderror" name="tel" value="{{ old('tel') }}" required autocomplete="tel" autofocus>

        @error('tel')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>
</div>

{{-- ニックネーム --}}
<div class="row mb-3">
    <label for="nickname" class="col-md-4 col-form-label text-md-end">nickname</label>

    <div class="col-md-6">
				{{-- ※任意なのでrequired属性は不要 --}}
        <input id="nickname" type="text" class="form-control @error('nickname') is-invalid @enderror" name="nickname" value="{{ old('nickname') }}" autocomplete="nickname" autofocus>

        @error('nickname')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>
</div>

💡
これで画面周りもOK

参考サイト

ログインの入力項目を増やす

任意のログイン画面を作る方法は2つある

  • デフォルトのログイン画面をカスタマイズする✅

    一般的な会員機能ならカスタマイズで十分対応できる(?)

  • 新しくログイン画面を作る✅

    特殊な要件のときは新しくログイン画面を作る(?)

    https://www.petitmonte.com/php/laravel_original_login.html

💡
ここではデフォルトのログイン画面に以下を追加する。
・name

完成イメージ
Image in a image block

コントローラーを修正
  • バリデーションを追加する✅
  • ログインで使う項目を追加する✅

app/Http/Controllers/Auth/LoginController.php

// ①追記
use Illuminate\Http\Request;

class LoginController extends Controller
{
    // ②追記:バリデーション
    // 補足:vendor/laravel/ui/auth-backend/AuthenticatesUsers.php にある validateLoginメソッドをオーバーライド
    protected function validateLogin(Request $request)
    {
        $request->validate([
            $this->username() => 'required|string',         // メール
            'password' => 'required|string',                // パスワード
            'name' => 'required|string',                    // name
        ]);
    }

    // ③追記:ログイン画面から、ログイン処理に渡すデータ
    // 補足:vendor/laravel/ui/auth-backend/AuthenticatesUsers.php にある credentialsメソッドをオーバーライド
    protected function credentials(Request $request)
    {
        return $request->only($this->username(), 'password', 'name');
    }
}

💡
これでログイン処理はOK

ビューを修正
  • 画面に入力項目を追加する✅
    • <form>〜</form>の中に追加する。
    • 他の入力項目を真似すればOK。

resources/views/auth/login.blade.php

{{-- name --}}
<div class="row mb-3">
    <label for="name" class="col-md-4 col-form-label text-md-end">{{ __('name') }}</label>

    <div class="col-md-6">
        <input id="name" type="name" class="form-control @error('name') is-invalid @enderror" name="name" required autocomplete="name">

        @error('name')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>
</div>

💡
これで画面周りもOK

usersテーブル以外を使ってログインしたい場合は以下を参照。

その他のカスタマイズ

色々なサイトでカスタマイズ方法が紹介されているのでメモしておく✅

公式ドキュメント

基本的なカスタマイズは網羅されているので最初に確認してみるといい。

入力項目追加 + 登録内容変更ページを作る

ユーザー管理機能

パスワードの変更

参考サイト

入力項目の追加は以下が分かりやすい

メール認証機能は以下が分かりやすい

メール認証の仕組み

ログイン・ログアウト後のリダイレクト

ユーザー情報の更新処理