設定
Laravelは認証をとてもシンプルに実現する目的を持っています。実際、最初から全てが設定済みです。認証の設定ファイルはapp/config/auth.php
で、認証機能の動作を調整するため、読みやすいコメントをつけた多くのオプションで構成されています。
LaravelはEloquent認証ドライバーでデフォルトとして使用されるUser
モデルをapp/models
ディレクトリーに用意してあります。このモデルのスキーマを作成する場合、パスワードフィールドは最低60文字必要であることを覚えておいてください。
もし、アプリケーションでEloquentを使用しないのであれば、database
認証ドライバーでクエリービルダーを使ってください。
注目: 認証を使い始める前に、
users
(もしくは同様の)テーブルにNULLを許す、100文字のremember_token
カラムを確実に用意してください。このカラムはアプリケーションで"Remember me"(持続的)セッションのトークンを保存するために使用されます。マイグレーション時に、$table->rememberToken();
を使用すれば作成されます。
パスワードの保存
LaravelのHash
クラスは安全なBcryptハッシュを提供しています。
Bcryptを使いパスワードをハッシュする
$password = Hash::make('secret');
ハッシュに対し、パスワードを確認する
if (Hash::check('secret', $hashedPassword))
{
// パスワード一致...
}
パスワードに再ハッシュが必要かチェックする
if (Hash::needsRehash($hashed))
{
$hashed = Hash::make('secret');
}
ユーザー認証
あるユーザーをアプリケーションにログインさせる場合は、Auth::attempt
メソッドを使います。
if (Auth::attempt(array('email' => $email, 'password' => $password)))
{
return Redirect::intended('dashboard');
}
email
が必須のオプションでないことに注意してください。主に例を示すために使っているだけです。データベースの中にあるどんなカラム名でも"username"に該当するものを使用できます。
Redirect::intended
関数は認証フィルターでキャッチされる前にアクセスしてきた、前のURLへユーザーをリダイレクトさせます。このメソッドにはフォールバックURIを指定機で、リダイレクト先へ転送できない場合に利用されます。
attempt
メソッドが呼び出された時にauth.attempt
イベントが発行されます。同様に、認証に成功した場合はauth.login
イベントが発行されます。
ユーザーが認証されているか判定する
ユーザーが既にアプリケーションへログインしているかをチェックするには、check
メソッドを使います。
if (Auth::check())
{
// ユーザーはログインしている…
}
ユーザーを認証し、ログインを保つ
アプリケーションで"Remember
me"機能を提供したい場合、attempt
メソッドの第2引数にtrue
を渡す必要があります。それにより無期限に(もしくは手動でログアウトされるまで)認証が維持されます。もちろんusers
テーブルに、"Remember
me"トークンを保存するために使用する、文字列のremember_token
カラムを用意しておく必要があります。
if (Auth::attempt(array('email' => $email, 'password' => $password), true))
{
// このユーザーは覚えられた...
}
注意:attempt
メソッドがtrue
を返す場合、そのユーザーはアプリケーションにログイン中だと考えられます。
ユーザーがRemember meで認証されているかを判定する
ユーザーのログインを覚えておく設定の場合、viaRemember
メソッドを使用し、そのユーザーが"remember
me"(ログインしたままにする)クッキーを使用して認証されているのかを判定できます。
if (Auth::viaRemember())
{
//
}
条件付きのユーザー認証を行う
認証のクエリーに条件を追加することも可能です。
if (Auth::attempt(array('email' => $email, 'password' => $password, 'active' => 1)))
{
// このユーザーは存在しており、アクティブで、使用停止ではない
}
注目:Session Fixation攻撃に対抗するため、認証後はセッションIDが自動的に再生成されます。
ログインしたユーザーにアクセスする
一度ユーザーが認証されると、Userモデル/レコードにアクセスできます。
$email = Auth::user()->email;
認証済みのユーザーのIDを取得するには、id
メソッドを使用します。
$id = Auth::id();
アプリケーションにユーザーをIDでログインさせたい時は、loginUsingId
メソッドを使用してください。
Auth::loginUsingId(1);
ログインしないで認証内容をチェックする
validate
メソッドでアプリケーションへ実際にログインさせずに、認証内容が正しいかをチェックできます。
if (Auth::validate($credentials))
{
//
}
そのセッションの間だけユーザーをログインさせる
そのリクエスト一回の間だけユーザーをログインさせるonce
メソッドも使用できます。これにはセッションもクッキーも使用されません。
if (Auth::once($credentials))
{
//
}
アプリケーションからログアウトする
Auth::logout();
ユーザーの手動ログイン
既に存在しているユーザーをアプリケーションにログインさせる場合、そのインスタンスを指定し、login
メソッドを呼び出してください。
$user = User::find(1);
Auth::login($user);
これはユーザー情報をもとにログインさせるattempt
と同じ状態になります。
ルートの保護
特定のルートへ認証済みのユーザーだけがアクセスできるように、ルートフィルターを使用できます。Laravelはデフォルトのauth
フィルターをapp/filters.php
で定義しています。
ルートを保護する
Route::get('profile', array('before' => 'auth', function()
{
// 認証済みのユーザーのみ入れる...
}));
CSRFからの保護
LaravelはCSRFからアプリケーションを簡単に守る手段を提供しています。
CSRFトークンをフォームへ埋め込む
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
送信されてきたCSRFトークンをバリデートする
Route::post('register', array('before' => 'csrf', function()
{
return '有効なCSRFトークンです!';
}));
HTTP基本認証
HTTP基本認証は専用の「ログイン」ページを作成しなくても手軽にユーザーを認証できる手法です。これを使用するにはauth.basic
フィルターをルートに追加してください。
HTTP基本認証でルートを保護する
Route::get('profile', array('before' => 'auth.basic', function()
{
// 認証済みのユーザーのみ入れる...
}));
デフォルトで、basic
フィルターはユーザーレコードのemail
カラムを認証に使用します。ユーザーの他のカラムを使用する場合は、app/filters.php
の中で、そのカラム名をbasic
メソッドの最初の引数として渡してください。
Route::filter('auth.basic', function()
{
return Auth::basic('username');
});
ステートレスなHTTP基本フィルターをセットする
またHTTP基本認証はセッションのユーザー識別クッキーをセットせず使用することができます。これは特にAPI認証に便利です。使用するには、onceBasic
メソッドをリターンするフィルターを書いてください。
Route::filter('basic.once', function()
{
return Auth::onceBasic();
});
PHP
FastCGIを使用している場合、デフォルトでHTTP基本認証は正しく動作しません。.htaccess
ファイルに以下の行を追加してください。
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
パスワードリマインダーとリセット
モデルとテーブル
ほとんどのWebアプリケーションはユーザーが忘れてしまったパスワードをリセットする手段を提供しています。それぞれのアプリケーションに毎回実装する代わりに、Laravelはパスワードリマインダーを送信し、パスワードをリセットする便利なメソッドを提供しています。最初にIlluminate\Auth\Reminders\RemindableInterface
がUser
モデルへ確実に実装されていることを確認してください。もちろん、フレームワークに含まれるUser
モデルには、このインターフェイスが最初から実装されています。そしてインターフェイスの実装に必要なメソッドを含んでいる、Illuminate\Auth\Reminders\RemindableTrait
を使用しています。
RemindableInterfaceを実装する
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements RemindableInterface {
use RemindableTrait;
}
リマインダーテーブルのマイグレーションを生成する
次に、パスワードリセットトークンを保存するテーブルを生成します。このテーブルのマイグレーションを生成するためには、単にArtisanコマンドのauth::reminders
を実行するだけです。
php artisan auth:reminders-table
php artisan migrate
パスワードリマインダーコントローラー
これでパスワードリマインダーコントローラーを生成する準備が整いました。auth:reminders-controller
Artisanコマンドを使用し、コントローラーを自動的に生成しましょう。app/controllers
ディレクトリー中に、RemindersController.php
を生成します。
php artisan auth:reminders-controller
生成されたコントローラーには、あなたが表示したパスワードリマインダーフォームを処理する、getRemind
メソッドが既に用意されています。あなたが行う必要があるのは、password.remind
ビューを作成することだけです。このビューはemail
フィールドを持つ、基本的なフォームです。フォームはRemindersController@postRemind
アクションへPOSTする必要があります。
シンプルなpassword.remind
ビューは以下のようになるでしょう。
<form action="{{ action('RemindersController@postRemind') }}" method="POST">
<input type="email" name="email">
<input type="submit" value="Send Reminder">
</form>
getRemind
に加えて、生成されたコントローラーはpostRemind
メソッドも持っています。これはパスワードリマインダーメールをユーザーに送信する処理を行います。このメソッドは、POST
変数にemail
フィールドが存在していることを期待しています。リマインダーメールがユーザーへ無事に送られれば、status
メッセージがフラッシュデーターとしてセッションに保存されます。送信に失敗すれば、error
メッセージが保存されます。
postRemind
コントローラーメソッドの中では、ユーザーへ送信する前に、メッセージインスタンスを更新することができます。
Password::remind(Input::only('email'), function($message)
{
$message->subject('Password Reminder');
});
ユーザーはコントローラーのgetReset
メソッドへルーティングされるリンクを含んだメールを受け取ります。指定されたパスワードリマインダーを識別するために使用されるパスワードリマインダートークンも一緒に送信されてきます。アクションにはpassword.reset
ビューを返すように、予めコードされていますが、このビューも作成して下さい。トークンはビューに渡され、token
という名前の隠しフォーム隠しフィールドとして設置されなくてはなりません。このtoken
に加え、パスワードリセットフォームにはemail
とpassword
、password_confirmation
フィールドが必要です。フォームはRemaindersController@postReset
メソッドへPOSTで送信して下さい。
シンプルなpassword.reset
ビューは下のようになるでしょう。
<form action="{{ action('RemindersController@postReset') }}" method="POST">
<input type="hidden" name="token" value="{{ $token }}">
<input type="email" name="email">
<input type="password" name="password">
<input type="password" name="password_confirmation">
<input type="submit" value="Reset Password">
</form>
最後に、postReset
メソッドがストレージ上のパスワードを実際に変更する責任を負います。このコントローラーアクションの中で、Password::reset
メソッドに渡されたクロージャーは、User
にpassword
属性をセットし、save
メソッドを呼び出しています。もちろん、このクロージャーは、User
モデルがEloquentモデルであると想定しています。しかしながら、アプリケーションのデータベース保管システムに適するように、必要に応じて自由に変更して下さい。
パスワードがうまくリセットし終えたら、ユーザーはアプリケーションのルートへリダイレクトされます。このリダイレクトURLも自由に変更して下さい。パスワードリセットが失敗したら、ユーザーはリセットフォームへ戻るようにリダイレクトされます。そして、error
メッセージがセッションにフラッシュデーターとして保存されます。
パスワードのバリデーション
デフォルトでは、Password::reset
メソッドは確認領域と同一であることと、6文字以上であることを確認します。クロージャーを使うPassword::validator
メソッドで、このルールを変更できます。クロージャーの中でどんなパスワードバリデーションも実行できます。パスワードが確認フィールドと一致するかを調べる必要がないことに注意して下さい。これはフレームワークにより、自動的に調べられます。
Password::validator(function($credentials)
{
return strlen($credentials['password']) >= 6;
});
Note: デフォルトでは、パスワードのリセットトークンは1時間で無効になります。
app/config/auth.php
ファイルのreminder.expire
オプションにより、この時間を変更できます。
暗号化
Laravelはmcrypt PHP拡張による、強力なAES暗号化機能を提供しています。
値を暗号化する
$encrypted = Crypt::encrypt('secret');
注目:
app/config/app.php
ファイルのkey
オプションに16文字か24文字、32文字のランダムな文字列を確実に設定してください。そうしないと、暗号化された値は安全ではありません。
値を解読する
$decrypted = Crypt::decrypt($encryptedValue);
手法とモードを設定する
暗号化に使用する手法とモードもセットできます。
Crypt::setMode('ctr');
Crypt::setCipher($cipher);
認証ドライバー
Laravelでは最初から、database
とeloquent
認証ドライバーが用意されています。他の認証ドライバーを追加するための情報は、認証の拡張に関するドキュメントをご覧ください。