イントロダクション
Laravelでは簡単に認証が実装できます。実際ほとんど全て、最初から設定済みです。認証の設定ファイルは、config/auth.php
に用意してあり、認証サービスの振る舞いを調整できるように、読みやすいコメント付きで、たくさんのオプションが用意されています。
Laravelはデフォルトとして、app
ディレクトリーの中の、App/User
モデルを読み込みます。このモデルはデフォルトのEloquent認証ドライバーと共に使用されます。
重要:
このモデルのデータベーススキーマを定義するとき、パスワード(password
)カラムは最低でも60文字にしてください。また使用する前に、空文字列を許し(NULLABLE)100文字の文字列のremember_token
カラムをusers
(もしくは同様の)テーブルへ確実に定義してください。マイグレーション中に$table->rememberToken();
を使い定義すれば、このカラムが設定されます。もちろん、Laravel5には、これらのカラムのためのマイグレーションを最初から用意してあります!
アプリケーションでEloquentを使用しない場合は、Laravelクエリービルダーを使用する、database
ドライバーを使用してください。
ユーザー認証
Laravelでは認証に関連する2つのコントローラーが用意されています。AuthController
は、新ユーザーの登録と、「ログイン」を処理します。もうひとつのPasswordController
には、登録済みユーザーがパスワードを忘れた時にリセットするためのロジックが準備されています。
必要なメソッドを読み込むために、両方のコントローラーでトレイトが使われています。多くのアプリケーションで、これらのコントローラーを変更する必要は全く無いでしょう。これらのコントローラーが表示するビューは、resources/views/auth
ディレクトリーにあります。こちらはお望み通り、自由に変更してください。
ユーザ登録
アプリケーションに新しいユーザーを登録するときに利用する、フォームのフィールドを変更するためには、App\Services\Registrar
クラスを変更してください。このクラスは、バリデーションとアプリケーションの新ユーザーを作成することに責任を持っています。
Registrar
のvalidator
メソッドは、アプリケーションの新ユーザーに対する、バリデーションルールで構成されています。一方で、Registrar
のcreate
メソッドは、データベースに新しいUser
レコードを作成することに責任を持っています。両メソッドとも、お好きなように変更してかまいません。Registrar
はAuthController
により、AuthenticatesAndRegistersUsers
トレイトの中のメソッドを通じて呼びだされます。
手動認証
提供しているAuthController
実装を使用しない選択をする場合は、Laravel認証クラスを直接使用し、ユーザーの認証を管理する必要があります。心配ありません。それでも、簡単ですよ!attempt
メソッドを最初に見てみましょう。
<?php namespace App\Http\Controllers;
use Auth;
use Illuminate\Routing\Controller;
class AuthController extends Controller {
/**
* 認証の確認作業を処理する
*
* @return Response
*/
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password]))
{
return redirect()->intended('dashboard');
}
}
}
attempt
メソッドは最初の引数として、キー/値ペアの配列を受け取ります。password
値はハッシュされている必要があります。配列中の他の値は、データベーステーブルの中から、そのユーザーを見つけるために使用されます。ですから、上の例ではemail
カラムの値により、ユーザーが取得されます。ユーザーが見つかれば、配列でメソッドに渡されたハッシュ済みのpassword
値と、データベースに保存してあったハッシュ済みpassword
が比較されます。2つのハッシュ済みパスワードが一致したら、そのユーザーの新しい認証セッションが開始されます。
attempt
メソッドは、認証が成功すればtrue
を返します。失敗時はfalse
を返します。
注意: この例のように、
intended
リダイレクトメソッドは、認証フィルターにかかる前に、アクセスしようとしていたURLへ、ユーザーをリダイレクトしてくれます。そのリダイレクトが不可能な場合の移動先として、フォールバックURIをこのメソッドに指定できます。
条件付きユーザー認証
認証時のクエリーに、追加の条件を指定することも可能です。
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1]))
{
// ユーザーは存在し、アクティブになっている
}
ユーザー認証済みの判定
ユーザーがアプリケーションにログインしているかを判断するには、check
メソッドを使用してください。
if (Auth::check())
{
// ユーザーはログイン済み…
}
ユーザー認証とログインの持続
アプリケーションでログイン維持(Remember
me)機能を持たせたい場合は、attempt
メソッドの第2引数に論理値でtrue
を指定します。ユーザーが自分でログアウトしない限り、認証が持続するようになります。もちろん、"remember
me"トークンを保存するために使用する、文字列のremember_token
カラムをusers
テーブルに持たせる必要があります。
if (Auth::attempt(['email' => $email, 'password' => $password], $remember))
{
// $rememberがtrueであれば、このユーザーは覚えられた…
}
この機能を使用している時に、ユーザーが、"remember
me"クッキーを使用して認証されているかを判定するには、viaRemember
メソッドを使用します。
if (Auth::viaRemember())
{
//
}
IDによるユーザー認証
ユーザーをアプリケーションへ、IDによりログインさせる場合は、loginUsingId
メソッドを使います。
Auth::loginUsingId(1);
ログインさせずに認証データー確認
アプリケーションにユーザーを実際にログインさせずに、認証データーを確認だけしたい場合は、validate
メソッドを使用してください。
if (Auth::validate($credentials))
{
//
}
リクエスト1回のみのユーザーログイン
once
メソッドを使用すると、アプリケーションにユーザーをそのリクエストの間だけログインさせることができます。セッションもクッキーも使用されません。
if (Auth::once($credentials))
{
//
}
ユーザーの手動ログイン
アプリケーションに、既に存在するユーザーインスタンスを用いてログインさせる必要がある場合、login
メソッドへ渡し、呼び出してください。
Auth::login($user);
これは認証データーを使用し、attempt
メソッドでログインした場合と同じように動作します。
アプリケーションからのログアウト
Auth::logout();
もちろん、組み込み済みのLaravel認証コントローラーを使用しているのでしたら、ユーザーをアプリケーションからログアウトさせるためのコントローラーメソッドは、最初から用意してあります。
認証イベント
attempt
メソッドが呼び出されると、auth.attempt
イベントが発行されます。認証が成功し、ユーザーがログインすると、auth.login
イベントが同様に発行されます。
認証済みユーザー情報の取得
一度ユーザーが認証されると、そのユーザーのインスタンスを取得する様々な方法が利用できます。
最初に、Auth
ファサードによりユーザーにアクセスしてみましょう。
<?php namespace App\Http\Controllers;
use Auth;
use Illuminate\Routing\Controller;
class ProfileController extends Controller {
/**
* ユーザープロファイルの更新
*
* @return Response
*/
public function updateProfile()
{
if (Auth::user())
{
// Auth::user()で認証済みユーザーのインスタンスが返される…
}
}
}
2つ目に、Illuminate\Http\Request
を利用して、認証済みユーザーへアクセスしてみましょう。
<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class ProfileController extends Controller {
/**
* ユーザープロファイルの更新
*
* @return Response
*/
public function updateProfile(Request $request)
{
if ($request->user())
{
// $request->user()は認証済みのユーザーインスタンスを返す
}
}
}
3つ目は、Illuminate\Contracts\Auth\Authenticatable
契約のタイプヒントを使用します。このタイプヒントはコントローラーのコンストラクターかコントローラーメソッド、もしくはサービスコンテナにより依存解決されるクラスのコンストラクターで指定します。
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use Illuminate\Contracts\Auth\Authenticatable;
class ProfileController extends Controller {
/**
* ユーザープロファイルの更新
*
* @return Response
*/
public function updateProfile(Authenticatable $user)
{
// $userは認証済みユーザーのインスタンス
}
}
ルート保護
ルートミドルウェアにより、認証済みユーザーだけが指定したルートへのアクセスを行えるようにできます。Laravelはデフォルトで、auth
ミドルウェアを提供しており、app\Http\Middleware\Authenticate.php
の中で定義されています。皆さんが必要なのは、これをルート定義で指定することだけです。
// ルートクロージャー使用の場合
Route::get('profile', ['middleware' => 'auth', function()
{
// 認証済みユーザーのみが入れる
}]);
// コントローラー使用の場合
Route::get('profile', ['middleware' => 'auth', 'uses' => 'ProfileController@show']);
HTTP基本認証
HTTP基本認証により、専用の「ログイン」ページを用意しなくても、素早くアプリケーションにユーザーをログインさせられます。これを使用するには、ルートにauth.basic
ミドルウェアを付けてください。
HTTP基本認証によるルート保護
Route::get('profile', ['middleware' => 'auth.basic', function()
{
// 認証済みユーザーのみが入れる
}]);
basic
フィルターはユーザー識別に、レコードのemail
カラムをデフォルトで使用します。
ステートレスなHTTP基本フィルター
セッションの識別クッキーを用いずに、HTTP基本認証を使用することもできます。これは特にAPI認証に便利です。実装するには、onceBasic
メソッドを呼び出すミドルウェアを定義してください。
public function handle($request, Closure $next)
{
return Auth::onceBasic() ?: $next($request);
}
PHP
FastCGIを使用している場合、HTTP基本認証は正しく動作しないでしょう。以下の行を.htaccess
ファイルへ追加してください。
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
パスワードリマインダーとリセット
モデルとテーブル
ほとんどのWebアプリケーションは、パスワードを忘れた場合にリセットする機能をユーザーへ提供しています。アプリケーションを構築するたびごとに、何度も実装しなくても済むように、Laravelはパスワードリマインダーを送信し、パスワードをリセットするための便利な手法を提供しています。
これを利用するには、User
モデルがIlluminate\Contracts\Auth\CanResetPassword
契約を実装しているか確認してください。もちろん、フレームワークに用意されているUser
モデルでは、既にこのインターフェイスが実装されています。Illuminate\Auth\Passwords\CanResetPassword
トレイトで、このインターフェイスで実装する必要のあるメソッドが定義されています。
リマインダーテーブルマイグレーションの生成
次に、パスワードリセットトークンを保存しておくためのテーブルを作成します。このテーブルのマイグレーションは、最初からLaravelのdatabase/migrations
ディレクトリーに含まれています。ですから、マイグレートするために必要なのは、次のコマンドだけです。
php artisan migrate
パスワードリマインダーコントローラー
Laravelには、ユーザーのパスワードをリセットするために必要なロジックで構成されたAuth\PasswordController
も備わっています。簡単に初められるように、ビューも用意しています!ビューはresources/views/auth
ディレクトリーにあります。アプリケーションのデザインに合わせ、思いのまま自由に変更してください。
PasswordController
のgetReset
メソッドへ張ったリンクをクリックすると、ユーザーはメールを受信することになります。このメソッドはパスワードリセットフォームを表示し、ユーザーがパスワードをリセットできるようにします。パスワードがリセットされると、そのユーザーは自動的にアプリケーションにログインされ、/home
へリダイレクトされます。リセット後のリダイレクト先をカスタマイズするには、PasswordController
のredirectTo
プロパティを定義してください。
protected $redirectTo = '/dashboard';
注意: パスワードリセットトークンの有効時間は、デフォルトで1時間です。
config/auth.php
ファイルの中の、reminder.expire
オプションで変更できます。
ソーシャル認証
典型的なフォームを元にした認証に加え、LaravelはLaravel Socialite(ソシエリート:名士)による、OAuthプロバイダーを利用した簡単で便利な認証方法も提供します。Socialiteは現在、Facebook、Twitter、Google、GitHub、Bitbucketをサポートしています。
Socialiteを使用する場合、composer.json
にパッケージを追加してください。
"laravel/socialite": "~2.0"
次に、config/app.php
設定ファイルで、Laravel\Socialite\SocialiteServiceProvider
を登録します。ファサードを追加するのもよいでしょう。
'Socialize' => 'Laravel\Socialite\Facades\Socialite',
続いてアプリケーションで使用するOAuthサービスの認証情報を追加する必要があります。認証情報は、config/services.php
設定ファイルで指定します。アプリケーションに必要なプロバイダーにより、facebook
、twitter
、google
、github
のキーを設定してください。
'github' => [
'client_id' => 'your-github-app-id',
'client_secret' => 'your-github-app-secret',
'redirect' => 'http://your-callback-url',
],
これでユーザーを認証する準備ができました!2つのルートを定義する必要があります。一つはOAuthプロバイダーへユーザーをリダイレクトするルート、もう一つは認証後に、プロバイダーからのコールバックを受け取るルートです。以下の例では、Socialize
ファサードを使用しています。
public function redirectToProvider()
{
return Socialize::with('github')->redirect();
}
public function handleProviderCallback()
{
$user = Socialize::with('github')->user();
// $user->token;
}
redirect
メソッドは、ユーザーをOAuthプロバイダーへ送る面倒を見ます。一方のuser
メソッドはリクエストを読み、プロバーダーからのユーザー情報を取得します。ユーザーをリダイレクトする前に、そのリクエストに"scopes"を指定することもできます。
return Socialize::with('github')->scopes(['scope1', 'scope2'])->redirect();
ユーザーのインスタンスを取得したら、そのユーザーに関する詳細情報をさらに得られます。
ユーザーの詳細情報取得
$user = Socialize::with('github')->user();
// OAuth Two プロバイダー
$token = $user->token;
// OAuth One プロバイダー
$token = $user->token;
$tokenSecret = $user->tokenSecret;
// 全プロバイダー
$user->getId();
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();