Laravel4、認証の新機能
タグ: Laravel4
Laravel4の認証機能を見て行きましょう。この記事は前記事の続きです。
*参照:UserクラスでCRUD
なお、この記事を書いているのはベータ4リリース後です。正式版では変更になる点もあるでしょう。ご注意ください。
ログイン
前回と同様、ルートの定義はroutes.phpで行います。
いつもユーザー名とパスワードではなんなんで、今回はユーザー名かメルアド、どちらでも認証できるように作成しました。
Route::get( '/login', function() { $warning = Session::get( 'warning', '' ); return View::make( 'user.login' ) ->with( 'warning', $warning ); } ); Route::post( '/login', array ( 'before' => 'csrf', function() { $inputs = Input::only( array ( 'username', 'email', 'password' ) ); if ( $inputs['username'] == "" and $inputs['email'] == "" ) { return Redirect::back() ->withInput() ->with( 'warning', 'ユーザー名、もしくはメールアドレスのどちらかを指定してください。' ); } $rules = array ( 'password' => array ( 'required' ), ); $val = Validator::make( $inputs, $rules ); if ( $val->fails() ) { return Redirect::back() ->withErrors( $val ) ->withInput() ->with( 'warning', 'バリデーションエラーです。' ); } if ( !Auth::attempt( array_only( $inputs, array ( 'username', 'password' ) ) ) ) { if ( !Auth::attempt( array_only( $inputs, array ( 'email', 'password' ) ) ) ) { return Redirect::back() ->withInput() ->with( 'warning', 'ユーザー名/メールアドレスとパスワードの組み合わせが異なっているようです。' ); } } return Redirect::to( '/' ); } ) );
ビューはapp/views/login.phpです。
@if (isset($warning)) {{ $warning }} @endif {{ Form::open() }} <p> {{ Form::label('username', 'ユーザー名') }} {{ Form::text('username', Input::old('username', '')) }} {{ $errors->first('username') }} </p> <p> {{ Form::label('email', 'メールアドレス') }} {{ Form::text('email', Input::old('email', '')) }} {{ $errors->first('email') }} </p> <p> {{ Form::label('password', 'パスワード') }} {{ Form::password('password') }} {{ $errors->first('password') }} </p> {{ Form::submit('ログイン') }} {{ Form::token() }} {{ Form::close() }}
さて、変更になったのは、ユーザー認証をAuth::attempt()で行うのですが、どのテーブル上のカラムであっても認証に利用できるようになりました。
Laravel3でも可能だった?その通りですが、設定ファイルで指定する必要がありました。Laravel4では、設定ファイルで指定する必要は無くなりました。attemptで渡した配列内の項目を使用して認証します。
この配列は1.passwordを含み、2.それ以外の項目で一意にレコードが決まる必要があります。(そうでないと、まともに認証できませんからね。)
簡単に言えばパスワードの他にユーザー名を使用するなら、ユーザー名だけでSELECTして、レコードが1件のみ引けるように、重複を許さないようにします。メールアドレスを使用する場合も同様、重複を許しません。
もし、例えばメールアドレスとユーザー名の重複を許し、その代わりに2つの組み合わせで一意になるようにユーザー登録を行えば、メールアドレスとユーザー名両方とパスワードの組み合わせで、認証するシステムも作成できます。(できますが、ユーザーは嫌がるでしょう。入力が面倒ですからね。)
上記のルート定義では、最初にユーザー名とパスワードで認証を行い、失敗したらメールアドレスとパスワードで認証を行なっています。こんなことが簡単にできるようになりました。
今回のusersにはランクカラムを入れてあります。100が管理者、1が一般ユーザーです。これを利用してスーパーユーザーのみログインさせる専門のページを作成できます。
ビューはsuperlogin.blade.phpです。
@if (isset($warning)) {{ $warning }} @endif {{ Form::open() }} <p> {{ Form::label('username', 'ユーザー名') }} {{ Form::text('username', Input::old('username', '')) }} {{ $errors->first('username') }} </p> <p> {{ Form::label('password', 'パスワード') }} {{ Form::password('password') }} {{ $errors->first('password') }} </p> {{ Form::submit('管理者ログイン') }} {{ Form::token() }} {{ Form::close() }}
代わり映えしません。ルートは次のようになります。
Route::get( '/superlogin', function() { $warning = Session::get( 'warning', '' ); return View::make( 'user.superlogin' ) ->with( 'warning', $warning ); } ); Route::post( '/superlogin', array ( 'before' => 'csrf', function() { $inputs = Input::only( array ( 'username', 'password' ) ); $rules = array ( 'password' => array ( 'required' ), ); $val = Validator::make( $inputs, $rules ); if ( $val->fails() ) { return Redirect::back() ->withErrors( $val ) ->withInput() ->with( 'warning', 'バリデーションエラーです。' ); } $inputs['rank'] = 100; if ( !Auth::attempt( $inputs ) ) { return Redirect::back() ->withInput() ->with( 'warning', 'ユーザー名/メールアドレスとパスワードの組み合わせが異なっているようです。' ); } return Redirect::to( '/' ); } ) );
ネタを開かせば、'rank'=>100
の配列アイテムを付け加え、認証を行なっているだけです。ドキュメントでは、ユーザーアカウントの停止を調べたり、アクティブであるかをチェックしたりする例が示されています。いろいろ、応用可能ですね。