RitoLabo

LaravelのAuth認証機能をカスタマイズし意図した挙動へ変更するTips

  • 公開:
  • 更新:
  • カテゴリ: PHP Laravel
  • タグ: PHP,Laravel,5.5,5.4,5.3,Auth,5.6

これまでのAuthシリーズでは、導入から機能拡張を行ってきました。今回は、Authまわりそのものをカスタマイズし、基本機能である「ログイン」「ユーザ登録」「パスワードリセット」に対しての挙動を自分の意図したものへ変更する操作を行います。

アジェンダ
  1. 開発環境
  2. ログイン後のリダイレクト先を変更する
  3. 認証対象カラムの変更
  4. ユーザ登録(作成)とバリデーションのカスタマイズ
  5. ログイン・ユーザ登録などAuth認証で使うURLを変更する

開発環境

今回の開発環境は以下の通りです。

  • Linux CentOS 7
  • Apache 2.4
  • MySQL 5.7
  • PHP 7.2/7.1
  • Laravel

Laravelのバージョンについては、5.6/5.5/5.4/5.3にて動作確認済みです。

Laravelのルートディレクトリを「laravel/」とします。

ログイン後のリダイレクト先を変更する

デフォルトでは、認証に通ったら/homeへリダイレクトされますが、意図したページへ遷移させたい場合があります。

その時はRedirectIfAuthenticatedミドルウェアでリダイレクト先を設定できます。

laravel/App/Http/Middleware/RedirectIfAuthenticated.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/path/page');
}

return $next($request);
}
}

/path/page の部分に任意のページを設定する事でリダイレクト先を変更する事ができます。

また、LoginControllerを編集する事でもリダイレクト先を変更できます。

laravel/app/Http/Controllers/Auth/LoginController.php
<?php

namespace App\Http\Controllers\Auth;

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

class LoginController extends Controller
{
use AuthenticatesUsers;

protected $redirectTo = '/home';

public function __construct()
{
$this->middleware('guest')->except('logout');
}
}

ちなみに、両方で違うリダイレクト先を設定した場合は、ミドルウェアで設定した方が優先されます。

認証対象カラムの変更

Laravelの認証は、デフォルトでメールアドレス+パスワードで認証を行うようになっています。

メールアドレスではなく、別のもので認証を行いたい場合は、LoginControllerを編集します。

laravel/app/Http/Controllers/Auth/LoginController.php
<?php

namespace App\Http\Controllers\Auth;

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

class LoginController extends Controller
{
use AuthenticatesUsers;

protected $redirectTo = '/home';

public function __construct()
{
$this->middleware('guest')->except('logout');
}

public function username()
{
return 'email';
}
}

一番下です。username()メソッドを追加しています。上記例では「email」を設定しているのでデフォルトと同じですが、例えばここを「username」と変更する事で、認証対象をメールアドレスからユーザ名に切り替える事ができます。

どうしてusername()メソッドという奇妙な名称のメソッドを実装する事で認証対象が切り替わるのか。ということですが、LoginControllerが継承しているAuthenticatesUsersトレイトにて元のusername()メソッドが実装されており、LoginController上でusername()メソッドを改めて定義する事で、継承元のメソッドが上書きされるからです。

ちなみに、認証対象のカラムを変更する際は、そのカラムがユニークであることが条件になります。

ユーザ登録(作成)とバリデーションのカスタマイズ

Laravelのユーザ登録機能は便利ですが、案件によってはデフォルトのものだけでなく、他にも必要なユーザ情報を持ちたい場合があります。権限とか、所属先とか。

そんな時は、RegisterControllerを編集する事でユーザ情報をカスタマイズする事が可能です。

laravel/app/Http/Controllers/Auth/RegisterController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Models\AuthUser;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;

class RegisterController extends Controller
{
use RegistersUsers;

protected $redirectTo = '/client/ctrlpanel';

public function __construct()
{
$this->middleware('guest');
}

protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:mst_user',
'password' => 'required|min:6|confirmed',
]);
}

protected function create(array $data)
{
return AuthUser::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'uuid' => uniqid(),
]);
}
}

create()メソッドにて登録に関するカスタマイズを、validator()メソッドにてユーザ登録時のバリデーションをカスタマイズする事ができます。

もちろん、ここを変更するのであれば、ユーザ登録画面のテンプレートを編集してフォームを追加する。そしてマイグレーションにも変更分を記述してテーブル構造を変更する事を忘れないでください。

ログイン・ユーザ登録などAuth認証で使うURLを変更する

Laravelには、ログインやパスワードリセットなど認証周りの機能を簡単に構築する事が出来ますが、デフォルトではURL(ログインページのURLなど)が決まっているので、要件によってはそのURLを変更したい場合もあります。

今回はAuth機能で使われるページのURLを変更し、任意のURLでそれらを動作するようにしていきます。

デフォルトのURLや設定

まずは、Auth認証機能をデフォルトのまま使った場合です。URLは以下のようになっています。

ログイン
/login
ログアウト
/logout
ユーザ登録
/register
パスワードリセット
/password/reset

これらを任意のURIに変更します。

Auth機能を構築する際に、ほどんとの場合artisanコマンドで必要なクラスや設定を一発構築すると思います。なのでコマンドを叩いた時にどこでどのような設定が行われ、どこにどんなクラス(ファイル)が生成されているかなどを把握できていると、URLの変更もわりとスムーズにいきます。

ルーティング

Auth機能のURLを変更するには、ルーティングを変更します。

まずは、Auth機能のルーティングを司る以下をコメントアウト、もしくは削除します。

laravel/routes/web.php
Auth::routes();
// ↓ コメントアウト、または削除
// Auth::routes();

上記の記述で、Auth機能に必要なルーティングが自動でセットされる仕組みになっています。つまり、デフォルトのURLでログインページなどが表示されるのは、この記述があるおかげです。

ちなみにこのAuthファサードのroutes()メソッドで何が動いているのかと言うと、以下の設定が呼び出されセットされています。

laravel/vendor/laravel/framework/src/Illuminate/Routing/Router.php
public function auth()
{
// Authentication Routes...
$this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController@login');
$this->post('logout', 'Auth\LoginController@logout')->name('logout');

// Registration Routes...
$this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
$this->post('register', 'Auth\RegisterController@register');

// Password Reset Routes...
$this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController@reset');
}

つまり、これらを個別でセットしてあげる事で、URLの変更が可能になります。

laravel/routes/web.php
Route::get('members/login', 'Auth\LoginController@showLoginForm')->name('login');
Route::post('members/login', 'Auth\LoginController@login');
Route::post('members/logout', 'Auth\LoginController@logout')->name('logout');

Route::get('members/register', 'Auth\RegisterController@showRegistrationForm')->name('register');
Route::post('members/register', 'Auth\RegisterController@register');

Route::get('members/password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
Route::post('members/password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
Route::get('members/password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
Route::post('members/password/reset', 'Auth\ResetPasswordController@reset');

デフォルトの前にmembersを追加してあります。これでURLの変更が完了です。試しにアクセスしてみます。

URL変更後のログインページ

変更した/members/loginでアクセスできました。もちろん、ログイン・ログアウト以外にも、パスワードリセットなどもできます。

まとめ

以上で作業は完了です。Auth機能はすぐにログインまわりを構築できる便利なものですが、それらもまた、柔軟に挙動を書き換える事が出来、自分の意図した通りにカスタマイズできます。

このページのTipsについては随時追加していきます。