ログインシステムの作成

ここでは、Artisanを使用せずに、
ログインシステムを作成する方法について説明する。

必要なテーブル

password

カラムの型:VERCHAR(255) NotNull デフォルトなし
見てのとおり、パスワードである。
自動的にハッシュ化(暗号化)される。

remember_token

カラムの型:VARCHAR(100) デフォルト「NULL」
ログアウトするたびに更新される、暗号化された文字列。
これのおかげで、万一Cookieをコピーされても、
ログアウトすれば、ログアウト前のCookieが使えなくなり、
セッションハイジャックが極めて困難なものとなる
(完全ではないが、おそらくほぼ完全と言えるレベル)。

極端な話、必須なのは2つのカラムである。
パスワードと共に、ユーザー名などの照合したい他のカラムは、後で指定できる。

モデルの作成

もちろんデータベースを使用するため、モデルを作成する事になる。
しかし、継承させるのは「Eloquent」の「Model」ではなく、
「Authenticatable」である。

<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;
    
    protected $table = 'users_data';

    protected $fillable = [
        'user_name', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];
}

使い方自体は、従来のモデルとほぼ同様である。
クラスの名前も任意であり、「$table」変数でテーブル指定する事もできる。

「$fillable」には、更新してもよいテーブルを文字列で指定する。
「$hidden」はJSON生成時などに隠しておく項目だが、現在調査中。
とりあえず、「password」と「remember_token」は、入れておくとよい。

Authファサードを読み込む

まずはコントローラーに「Auth」を読み込ませる。
各コントローラーの継承元である、大本の「Controller.php」に記述するとよい。

use Illuminate\Support\Facades\Auth;

これで「Auth」ファサードが使えるようになる。

ログイン認証の方法

基本的には、フォームから入力されたパスワードなどで照合するが、
認証処理に限って言えば、単に値を入れればいいだけなので、
フォーム処理の部分は、ここでは割愛する。

複数の情報を、「Auth」ファサードの「attempt」メソッドで照合する。

Auth::attempt(['user_name' => $request->user_name, 'password' => $request->password])

連想配列で指定し、プロパティ名にはカラム名を、
配列の中身には、照合したい値を入力する。

この例では「user_name」と「password」の2カラムで照合を行う例だが、
照合するカラムを増やす事も可能である。
「password」のカラムだけ、照合処理時に自動的に暗号化処理されるので、
暗号化されていない値を、そのまま入れてもよい。
他の値については、自分で暗号化処理をする必要がある。

「Auth::attempt()」メソッドは、
照合に成功すれば「true」を、失敗すれば「false」を返す。

ログアウト処理

Auth::logout();

を、実行するだけである。

ログインしたユーザーの情報を取得する

「Auth::user()」メソッドを使用すれば、
現在ログイン中のユーザーのインスタンスが取得できる。

また、以下のようにすれば、ユーザーの情報を取得できる。

$user = Auth::user();
$userName = $user->user_name;

この例は、「user_name」カラムから情報を取得する場合である。
モデルのオブジェクトとほぼ同じように、
アロー演算子でカラム名を指定する事で、取得可能である。

コントローラーで使うには?

コントローラー上で「Auth::user()」を使うには、
コントローラーごとに「use Illuminate\Support\Facades\Auth;」で、
ファサードを読み込む必要がある。

しかし、いちいちコントローラーごとに記述しなければならないのは面倒なので、
以下のように、大本の「Controller」に、以下のようなメソッドを作成しておけばいい。

use Illuminate\Support\Facades\Auth;
class Controller extends BaseController
{
    protected function loginUser() {
        return Auth::user();
    }
}

このように、「Auth::user()」を返すメソッドを作っておけば、
この例の場合、「$this->loginUser()」を呼び出す事により、
「Auth::user()」ファサードと同じオブジェクトを呼び出せる。

ただし、ビュー上ではコントローラーで読み込んだファサード等を、そのまま使う事ができ、
「Auth::user()」を直に使う事ができる。

ユーザー情報の変更

ユーザー情報を変更するには、改めてモデルを作成したりする必要はない。
認証のために作成されたモデルは、「Authenticatable」を継承しているものの、
「Eloquent」のモデルと同じように扱えるので、
認証のために作成したモデルを、そのまま使って更新するとよい。

ユーザー情報を変更したけど、反映されない?

ユーザー情報を更新した直後に、「Auth::user()」を呼び出しても、
更新が反映されていない場合がある。
それはデータベースは変更されたものの、
PHP側のAuthオブジェクトが更新されていないためと思われる。

更新を行うコントローラーのメソッド上で、そのままビューを呼び出すのではなく、
一度「redirect()」メソッドでリダイレクトしてみるとよい。