【Laravel6】Laravelの認証機能をメールアドレスとユーザー名のどちらでもログイン可能にする方法

スポンサーリンク

Laravelの認証機能とは以下のコマンドで追加したものです。

php artisan ui vue --auth

または

php artisan ui react --auth

Laravelの認証機能はデフォルトで、メールアドレスとパスワードでログインできますよね。

それをメルアドレスorユーザ名+パスワードでログインできるようにする方法を紹介します。

[app/Http/Controllers/Auth/LoginController.php]※追加する部分のみ記載

use Illuminate\Http\Request;
    // --前後のソースは省略
    /**
     * Get the login username to be used by the controller.
     * AuthenticatesUsersのusernameをオーバーライド
     *
     * @return string
     */
    public function username()
    {
        // もし、DBに別の名前でユーザー名のカラムを作っていたらここを変える。
        return 'name';
    }

    /**
     * Get the needed authorization credentials from the request.
     * AuthenticatesUsersのcredentialsをオーバーライド
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function credentials(Request $request)
    {
        // フォームからの値を取得
        $username = $request->input($this->username());
        $password = $request->input('password');
        // usernameがemail形式かを判定
        if (filter_var($username, FILTER_VALIDATE_EMAIL)) {
            // email形式の場合は連想配列のkey=emailに値を渡す
            return  ['email' => $username, 'password' => $password];
        } else {
            // email形式でない場合は連想配列のkey=nameに値を渡す
            return [$this->username() => $username, 'password' => $password];
        }
    }

AuthenticatesUsersクラスのusernameとcredentialsメソッドをオーバーライドして処理を書き換えている。

[resources/views/auth/login.blade.php]※修正する部分のみ記載

emailをnameに書き換える

<div class="form-group row">
{{-- <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> --}}
    <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</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> --}}
    <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
{{--    @error('email') --}}
        @error('name')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>
</div>

[app/Http/Controllers/Auth/RegisterController.php]※修正する部分のみ記載

※Usersテーブルのnameに登録する際のValidatorも修正しないといけない。

/**
 * 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'],
        'name' => ['required', 'string', 'alpha_num', 'max:255', 'unique:users'],
//      'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
        'email' => ['required', 'string', 'email:filter', 'max:255', 'unique:users'],
        'password' => ['required', 'string', 'min:8', 'confirmed'],
    ]);
}

nameのValidatorに’alpha_num’と’unique:users’を追加

'alpha_num’→文字なら何も入れていいとなると、emailと全く同じものを入れられると不都合が起きそうなため。emailとnameが同じ値でも問題ないかもしれないけど。。。

'unique:users’→認証に使うので一意でなければいけないため。

'email’のValidatorの’email’を’email:filter’に修正

'email:filter’→LoginController.phpでメールアドレス形式に使った「FILTER_VALIDATE_EMAIL」と同じ規則で判定するため。

 

これでメールアドレスでもユーザー名でもログインできるようになった。

スポンサーリンク

Laravel

Posted by ton