Laravelで作成したアプリケーションにgoogleやFacebookのアカウントでログインする方法は、様々なサイトで紹介されています。
その大部分がSocialiteやSAML2を利用するものですが、それらの機能でシングルサインオンを実現した後で、Laravelのアプリケーションのログインやユーザー登録との連携を記載されている記事が少ないような気がしたので、記事にすることにしました。
ここではgoogleアカウントを利用したSSO認証を例に、認証後のLaravelアプリケーションへのログインやユーザー登録方法を紹介します。
- ソーシャルログイン後に使用したユーザーを、Laravelアプリケーションにユーザー登録できる。
- ソーシャルログイン後に、Laravelアプリケーションに自動ログインできる。
前提条件
Laravel標準の認証機能(Auth)を使用していること
この記事で紹介する方法は、Laravel標準の認証機能(Auth)に組み込まれているコントローラーやブレードファイルをカスタマイズするものなので、Authが利用可能になっている必要があります。
# php artisan route:list
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
| | GET|HEAD | login | login | App\Http\Controllers\Auth\LoginController@showLoginForm | web |
| | | | | | AppHttpMiddlewareRedirectIfAuthenticated |
| | POST | login | | App\Http\Controllers\Auth\LoginController@login | web |
| | | | | | AppHttpMiddlewareRedirectIfAuthenticated |
| | POST | logout | logout | App\Http\Controllers\Auth\LoginController@logout | web |
| | GET|HEAD | password/confirm | password.confirm | App\Http\Controllers\Auth\ConfirmPasswordController@showConfirmForm | web |
| | | | | | AppHttpMiddlewareAuthenticate |
| | POST | password/confirm | | App\Http\Controllers\Auth\ConfirmPasswordController@confirm | web |
| | | | | | AppHttpMiddlewareAuthenticate |
| | POST | password/email | password.email | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail | web |
| | GET|HEAD | password/reset | password.request | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web |
| | POST | password/reset | password.update | App\Http\Controllers\Auth\ResetPasswordController@reset | web |
| | GET|HEAD | password/reset/{token} | password.reset | App\Http\Controllers\Auth\ResetPasswordController@showResetForm | web |
| | GET|HEAD | register | register | App\Http\Controllers\Auth\RegisterController@showRegistrationForm | web |
| | | | | | AppHttpMiddlewareRedirectIfAuthenticated |
| | POST | register | | App\Http\Controllers\Auth\RegisterController@register | web |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
認証プロバイダ側の設定が完了していること
今回の記事は、googleアカウントを利用したSSO認証を例にしているので、認証プロバイダ側の設定が完了している状態とは、Google Cloud Platform の「APIとサービス」にて「OAuth 2.0 クライアント ID」の設定が完了している状態です。
なお今回の記事では、googleアカウント認証後のリダイレクト先である「承認済みのリダイレクトURI」は、「http://localhost:8080/callback」として記述します。
ソーシャルログイン用のコードが稼働する状態であること
今回の記事はSocialiteを利用したソーシャルログインを例にしているので、コントローラーで以下コードが機能する状態です。
Socialite::driver('google')->redirect(); // googleアカウントログインへのリダイレクト
Socialite::driver('google')->stateless()->user(); // googleアカウント認証後のコールバック受信
ログイン画面表示部分を認証プロバイダへのリダイレクトに変更する
Authでのログイン画面表示は、LoginControllerクラスのshowLoginForm()メソッドで行っています。
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
| | GET|HEAD | login | login | App\Http\Controllers\Auth\LoginController@showLoginForm | web |
| | | | | | AppHttpMiddlewareRedirectIfAuthenticated |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
showLoginForm()は、 AuthenticatesUsersクラスから継承されたメソッドです。中身を見ると、「auth/login.blade.php」を表示していることがわかります。
public function showLoginForm()
{
return view('auth.login');
}
そこで、auth/login.blade.phpを表示させる代わりに、認証プロバイダにリダイレクトするよう、showLoginForm()をオーバーライドします。
public function showLoginForm()
{
return Socialite::driver('google')->redirect();
}
認証プロバイダからのコールバック処理を記述する
認証プロバイダからのコールバックされたユーザーが、アプリケーションに登録済みの場合はログイン、存在しなければユーザー登録をするようにします。
ログイン処理
Authでのログイン処理は、LoginControllerクラスのlogin()メソッドで行っています。
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
| | POST | login | | App\Http\Controllers\Auth\LoginController@login | web |
| | | | | | AppHttpMiddlewareRedirectIfAuthenticated |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
login()は AuthenticatesUsersクラスから継承されたメソッドです。しかし、login()メソッドによるアプリケーションへのログインには、ユーザーIDとパスワードが必要になるため、ユーザーIDのみでログインができる、AuthクラスのloginUsingId()メソッドを使用します。
ユーザー登録
Authでのユーザー登録は、RegisterControllerクラスのregister()メソッドで行っているので、コールバック処理時にregister()メソッドを呼び出すようにします。
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
| | POST | register | | App\Http\Controllers\Auth\RegisterController@register | web |
| | | | | | AppHttpMiddlewareRedirectIfAuthenticated |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+---------------------------------------------+
作成したコールバック処理
public function callback()
{
$_ = Socialite::driver('google')->stateless()->user();
$user = User::where('email',$_->email)->first(); // 認証プロバイダからの戻り値から、アプリケーションのログインIDを取得する
if (! empty($user))
{
Auth::loginUsingId($user->id); // ログインIDのみでアプリケーションにログインする。
return redirect($this->redirectTo); // ログイン後のリダイレクト
}
$request = new Request ;
$request->merge([
'name' => $_->name,
'email' => $_->email,
]);
$regist = new RegisterController;
return $regist->register($request) ;
}
ルーティングを設定する
認証プロバイダからコールバックされたときにだけ、アプリケーションへのログインやユーザー登録をさせるようにするため、ルーティングを変更します。
Auth::routes([
'register' => false, // ユーザー登録はプロバイダからのコールバック時に限定する
'reset' => false, // パスワード初期化:認証プロバイダを利用するのに不活性化
'confirm' => false, // パスワード確認:認証プロバイダを利用するのに不活性化
'verify' => false, // メール認証:認証プロバイダを利用するのに不活性化
]);
Route::get('callback', 'App\Http\Controllers\Auth\LoginController@callback'); // 認証プロバイダからのコールバック
Route::post('login' , function() {
return redirect('login'); // ログインは認証プロバイダからのコールバック時に限定する
}) ;
なお、最後の「Route::post(‘login’…」の部分は、外部からのLaravelのIDでのログインを無効化する対策です。
Authを使用することによって「Auth\LoginController@login」の呼び出しが可能になってしまうため、「/login」へのリダイレクト(「LoginController@showLoginForm」の呼び出し)に上書きしています。
まとめ
以上で、googleアカウントでの認証後に、Laravelアプリケーションへのログインやユーザー登録できるようになります。
参考になればうれしいです。
コメント