PHP フレームワーク『 Laravel 』入門 #7 ログイン機能とカスタマイズ方法

ログイン機能とカスタマイズ方法

Laravel にはこれまで紹介した便利なコマンドのほかに、Web アプリケーションを作るのに欠かせない認証・認可に関する機能が最初から用意されています。

その1つが、ユーザー登録を行った利用者だけが Web アプリケーションを閲覧・利用できるようにする「ログイン機能」です。

ログイン機能は、会員制の Web アプリケーションに欠かせません。それ以外にも、管理者ユーザーを作って、一般ユーザーにはできない操作を Web 上でさせたい場合に有用です。

一から作れば1~2日かかってしまうログイン機能ですが、Laravel では初めから用意されているので最短10分で導入できるのが強みです。

カスタマイズも簡単でとても便利ですので、ぜひ活用してください。

前回の内容は、こちらをご覧ください。
▶︎PHP フレームワーク『 Laravel 』入門 #6 Artisan オリジナルコマンドの作成と定期実行方法

目次

  1. 『 Laravel 』のログイン機能
    1.1 ログイン機能の有効化
    1.2 ログイン画面
    1.3 ユーザー登録画面
  2. ログイン機能のカスタマイズ
    2.1 ログインフォーム、ユーザー登録フォームの日本語化
    2.2 ユーザーIDでログインできるようにする
    2.3 ユーザー登録画面に項目を追加する
  3. 最後に

「Webサイトからお問い合わせが来ない…」とお悩みの方必見!
当サイトのノウハウを詰め込んだ『Web集客の無料ガイド』をご提供

1. 『 Laravel 』のログイン機能

Laravel で初めから用意されているログイン機能は、利用者のメールアドレスとパスワードを入力するだけの簡単なものです。

入力したメールアドレスがデータベースの Users テーブルに存在し、かつパスワードが一致した場合にログイン成功となります。開発者は、ログインに成功したユーザーだけが見られるページや、押せるボタンなどを設置することができます。

これだけでも機能的には十分ですが、もっと使いやすくするためのカスタマイズも可能です。

カスタマイズの方法は後述しますので、まずはデフォルトのままでログイン機能を有効化してみましょう。

1.1 ログイン機能の有効化

Laravel のログイン機能を有効化するには、Artisan make:auth コマンドを実行します。

# Laravelプロジェクト(PROJECT_NAME)に移動
cd ~/html/laravel/PROJECT_NAME
# ログイン機能を有効化する
php-7.1 artisan make:auth

Authentication scaffolding generated successfully.

というメッセージが表示されればコマンドは成功です。

驚くべきことに、たったこれだけでログイン機能に必要なファイルがプロジェクトに追加されます。

※データベースに User テーブルがまだ作成されていない場合はエラーになりますので、先にデータベースのマイグレーションを実行してください。

php-7.1 artisan migrate

 

生成されたログイン機能関係のクラスを Web アプリケーションに即座に反映させるため、以下のコマンドでキャッシュクリアを実行してください。

php-7.1 artisan clear-compiled
php-7.1 artisan optimize
php-7.1 artisan view:clear

 

artisan optimize の実行後に以下のようなエラーメッセージが表示されますが、無視をしても問題ありません。

LogicException  : Unable to prepare route [api/user] for serialization. Uses Closure.

 

キャッシュクリアの実行後、Web アプリケーションのトップページにアクセスすると、ヘッダー部分に「 LOGIN 」「 REGISTER 」というボタンが追加されているのが確認できます。

http://<サーバの公開URL>/laravel/PROJECT_NAME/public/

 width=

1.2 ログイン画面

ヘッダー部分に追加された「 LOGIN 」をクリックすると、ログイン画面が表示されます。

 width=

E-Mail Address:ユーザーのメールアドレス
Password:パスワード

Remember Me にチェックを入れてログインするとログイン情報がブラウザに記録されて、次回以降のログインが省略されます。

Forgot Your Password? は利用者がパスワードを忘れた際にパスワード再設定用リンクをメールで送る機能です。こちらもはじめから用意されていますので、とても便利です。

1.3 ユーザー登録画面

ヘッダー部分に追加された「 REGISTER 」をクリックすると、ユーザー登録画面が表示されます。

利用者はまずこの画面で自分のユーザー情報(認証情報)を登録します。

 width=

  • Name は利用者が希望するユーザー ID を入力します。
  • E-Mail Address は利用者が自身のメールアドレスを入力します。
  • Password は利用者が希望する、ログインの際に入力するパスワードを入力します。
  • Confirm Password は誤入力防止用で、再度希望するパスワードを入力します。

Laravel のログイン機能がデフォルトで取り扱うユーザー情報(認証情報)は上記のとおりです。

他に項目を増やしたい場合は、カスタマイズ方法を後述しますので、そちらをご参考ください。

実際にテストユーザーの登録を行ってみます。

1.4 テストユーザー登録

 width=

同一のメールアドレスがすでに登録されている場合は、エラーメッセージが表示されます。

テストユーザーを複数作成する際には、ユーザーごとに別のメールアドレスを用いてください。

ユーザーの登録が成功すると、自動的にダッシュボードページに移動します。

 width=

ヘッダーメニューの Logout をクリックすると、ログアウトされてトップページに戻ります。

2. ログイン機能のカスタマイズ

前章では Laravel ログイン機能について導入方法をご説明しました。

デフォルトの状態でも十分利用できますが、もっと使いやすく、Web アプリケーションの用途に合わせた内容にカスタマイズすることができます。

ここからカスタマイズの例をいくつかご紹介しますので、自分が開発する Web アプリケーションにも導入したいと思うものがあれば、ぜひ手順を参考に導入してみてください。

2.1 ログインフォーム、ユーザー登録フォームの日本語化

ログインフォーム、ユーザー登録フォームの項目はすべて英語で書かれています。

このままだとユーザーに不親切なため、日本語に変更します。

まずログイン画面の入力フォームを日本語に変更します。

resources/views/auth/login.blade.php

extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('login') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="email" class="col-md-4 col-form-label text-md-right">メールアドレス</label>

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

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

                        <div class="form-group row">
                            <label for="password" class="col-md-4 col-form-label text-md-right">パスワード</label>

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

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

                        <div class="form-group row">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">ログイン情報を保存する</label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">ログイン</button>

                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">パスワードを忘れましたか?</a>
                                @endif
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

 

次に、ユーザー登録画面の入力フォームを日本語に変更します。

resources/views/auth/register.blade.php

 extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Register') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('register') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="name" class="col-md-4 col-form-label text-md-right">ご希望のユーザーID</label>

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

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

                        <div class="form-group row">
                            <label for="email" class="col-md-4 col-form-label text-md-right">メールアドレス</label>

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

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

                        <div class="form-group row">
                            <label for="password" class="col-md-4 col-form-label text-md-right">パスワード</label>

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

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

                        <div class="form-group row">
                            <label for="password-confirm" class="col-md-4 col-form-label text-md-right">パスワード(確認のため再度入力してください)</label>

                            <div class="col-md-6">
                                <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
                            </div>
                        </div>

                        <div class="form-group row mb-0">
                            <div class="col-md-6 offset-md-4">
                                <button type="submit" class="btn btn-primary">登録する</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

2.2 ユーザー ID でログインできるようにする

Laravel のログイン機能はデフォルトではメールアドレスとパスワードの組み合わせで認証を行います。

これだとメールアドレスが長い場合に入力が面倒なため、ユーザー ID とパスワードでログインが可能になるようカスタマイズします。

まずはログイン機能のコントローラーに以下の記述を追加します。

app/Http/ Controllers/Auth/LoginController.php

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

use Illuminate\Http\Request;

class LoginController extends Controller
{
  
    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/home';
 

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
  
    public function username()
    {
      return 'name';
    }
}

username という関数を追加して、戻り値にログインに利用したいカラムの名前(今回はユーザー ID なので name )を文字列で指定します。

 

次に、ログイン画面の画面項目を変更します。

resources/views/auth/login.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('login') }}">
                        @csrf
                        <!-- メールアドレスの入力項目をコメントアウトする -->
                        <div class="form-group row">
                            <label for="email" class="col-md-4 col-form-label text-md-right">メールアドレス</label>

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

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>
                        -->
                       <!-- 新しくユーザーIDの入力項目を追加する -->
                       <div class="form-group row">
                            <label for="name" class="col-md-4 col-form-label text-md-right">ユーザID</label>

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

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

ログイン画面の入力フォームのうち、メールアドレスの入力フォームを削除します(今回は分かりやすいようにコメントアウトしています)。

そのかわりに、ユーザー ID の入力フォーム (input name=“name”) を新たに追加しています。

これでログインに用いる項目がメールアドレスからユーザー ID に変更されます。

2.3 ユーザー登録画面に項目を追加する

最後に、ユーザー登録画面に氏名や住所、電話番号などの独自の項目を追加する方法です。

少し複雑ですが、実際の Web アプリケーションでは会員登録を行う際にこれらの情報も登録させることが多いので、ぜひ覚えてご活用ください。

 

2.3.1 Users テーブルのカラム追加

まず、Users テーブルに氏名と電話番号のカラムを増やすためのマイグレーションファイルを作成します。

php-7.1 artisan make:migration update_user_table --table=users

database/migrations/日付_update_user_table.php

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class UpdateUserTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
          $table->string('fullname'); // 氏名カラムを追加
          $table->string('phone');  // 電話番号カラムを追加
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {

        });
    }
}

マイグレーションファイルの作成が終わったら、マイグレーションを実行します。

php-7.1 artisan migrate

成功するとデータベース上の Users テーブルに「 fullname 」「 phone 」のカラムが追加されます。

 width=

 

2.3.2 User モデルの変更

続いて、テーブルの変更にあわせて User モデルの内容を変更します。

app/User.php

<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',’fullname’,’phone’,
    ];

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

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

フィールドの $fillable 配列に新しく追加したカラム名「 fullname 」「 phone 」を追加しています。

この変更を忘れると、入力された氏名と電話番号を Users テーブルに登録する際にエラーになりますのでご注意ください。

 

2.3.3 入力フォームの変更

次に、ユーザー登録画面の入力フォームに氏名と電話番号の項目を追加します。

resources/views/auth/register.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Register') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('register') }}">
                        @csrf

~略~
                      
                        <div class="form-group row">
                            <label for="fullname" class="col-md-4 col-form-label text-md-right">氏名</label>

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

                                @error('fullname')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>     
                      
                        <div class="form-group row">
                            <label for="phone" class="col-md-4 col-form-label text-md-right">電話番号</label>

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

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

 

2.3.4 コントローラーの変更

最後に、ユーザー作成用のコントローラーファイルに、新しい項目のバリデーションルール(入力規則)と登録処理を追加します。

app/Http/ Controllers/Auth/RegisterController.php

<?php

namespace App\Http\Controllers\Auth;

use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;

class RegisterController extends Controller
{
    use RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    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'],
            'fullname' => ['required', 'string', 'max:255'],
            'phone' => ['required', 'string', 'max:50'],
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\User
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
            'fullname' => $data['fullname'],
            'phone' => $data['phone'],
        ]);
    }
}

validator 関数の戻り値に設定されている Validator::make は、それぞれの入力項目に対してどのようなチェックを行うかを記述します。

細かいバリデーションルールなどの説明は省略しますが、required を設定すると入力が必須になります。逆に何も定義しないと、任意入力の項目になります。

create 関数の User::create で Users テーブルへの登録を行っています。

ここに氏名と電話番号の代入処理を追加してください。

 

2.3.5 ユーザー情報の登録、確認

以上でユーザー登録フォームの項目追加カスタマイズの手順は完了です。

それでは、実際に登録をしてみます。

 width=

登録が完了したらダッシュボード画面に新しく追加した氏名と電話番号を表示して、正しく登録ができているか確認してみましょう。

resources/views/home.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Dashboard</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif
                    <h2>ようこそ、{{ Auth::user()->fullname }}さん!</h2>
                    <h3>連絡先:<a href="tel:{{ Auth::user()->phone }}">{{ Auth::user()->phone }}</a></h3>
                    
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

ログイン中のユーザーの情報は Auth::user で呼び出すことができます。

 width=

画像のように、氏名と電話番号が表示されていればカスタマイズ成功です。

3. 最後に

今回は Laravel の認証・認可機能のうちログイン機能についてご紹介しました。

Web アプリケーションを作成するうえで、ログイン機能は欠かせないものですので、ぜひ Laravel のログイン機能を使いこなして開発のスピードアップを実現させてください。

カスタマイズの方法は今回ご紹介したもの以外にもたくさんあります。自分が作りたい Web アプリケーションに最適なカスタマイズ方法を探してみてください。

関連タグ:

CPIの最新情報をTwitterでチェックできます!
@cpiadjp
次へ
前へ