目的
laravel5.0にて, ビルドインされているAuthコントローラでは
- password
を使って認証しているが, これを - name
- password
を使ったものに変えたい.
環境
php: 5.4
laravel: 5.0
既存コードを見てみる
プロジェクトを新規に作成した時点(あるいは, デフォルトで用意されたユーザテーブル用マイグレーションを実行した時点?)で作られている,
/app/Http/Controllers/AuthAuthController.php
というクラスが
ログイン/ログアウトの処理を行っているコントローラになります.
しかし, このファイルの内容を見ていただければわかると思いますが, 実際の処理は
Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers\AuthenticatesAndRegistersUsers
というtraitをuseしているだけであり, 実際の処理はそちらのtraitにかかれています.
ログイン時に呼び出されるAuthenticatesAndRegistersUsers#postLogin
メソッドを見てみましょう.
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email', 'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if ($this->auth->attempt($credentials, $request->has('remember')))
{
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'email' => $this->getFailedLoginMessage(),
]);
}
リクエストパラメータから, email
とpassword
を抜き出し, validationにかけたあとauth
オブジェクトで認証を試み(attempt)ているようです.
$this->auth
オブジェクトはIlluminate/Auth/Guard
クラスのインスタンスであり, attempメソッドの内容は以下のとおりです.
/**
* Attempt to authenticate a user using the given credentials.
*
* @param array $credentials
* @param bool $remember
* @param bool $login
* @return bool
*/
public function attempt(array $credentials = [], $remember = false, $login = true)
{
$this->fireAttemptEvent($credentials, $remember, $login);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials))
{
if ($login) $this->login($user, $remember);
{
return true;
}
}
return false;
}
見ての通り,
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
と認証用情報を元にユーザを検索して, validationかけて, OKならログイン成功という処理を行っているだけのようです.
providorについては未調査ですが, おそらくデフォルトのユーザテーブル以外のテーブルなどを使いたい時には
自作のproviderを用意してナンヤカンヤできるようになっているのだと思われます.
認証周りのコードを修正してみる
実際に, name+passwordでログインできるように修正していきます.
コントローラの修正
まず, /app/Controllers/Http/auth/AuthController.php
にログインリクエストを処理するpostLogin
メソッドを追加します.
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function postLogin(Request $request)
{
$this->validate($request, [
'name' => 'required', 'password' => 'required',
]);
$credentials = $request->only('name', 'password');
if ($this->auth->attempt($credentials, $request->has('remember')))
{
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only('name', 'remember'))
->withErrors([
'name' => $this->getFailedLoginMessage(),
]);
}
traitにも同名のメソッドがありますが, 継承先(traitの場合も継承先でいいのかな?)のメソッドが優先されるので
ログインリクエストからは, こちらのメソッドが呼び出されるようになります.
ついでに, ログイン失敗時のメッセージも変えておきましょう.
/**
* Get the failed login message.
*
* @return string
*/
protected function getFailedLoginMessage()
{
return '名前またはパスワードが違います';
}
ビューの修正
ログインビューは/resource/views/auth/login.blade.php
にあります.
いろいろと細かく書かれていますが, 今回は既存のemail用のテキストエリアをそのままname用のものに書き換えて流用します.
<div class="form-group">
<label class="col-md-4 control-label">Name</label>
<div class="col-md-6">
<input type="name" class="form-control" name="name" value="{{ old('name') }}">
</div>
</div>
動作確認
ブラウザから, 一度ログアウトした後, name+passwordでログインできたら成功です.