Laravelでソーシャルログインを実装してみました。
目次
Socialiteをインストールする
まず、Laravelにソーシャル認証用のプラグインSocialiteをインストールします。
Socialiteをインストールする方法は、以下の記事にまとめました。
Socialiteを使った実装方法については、以下の記事に実装例が書かれています。
これは、GitHubを使った例ですが、TwitterでもFacebookでもGoogle+でも、ほとんど差はありません。
私は、Twitter、Facebook、Google+で実装してみました。
Twitter、Facebook、Googleで、クライアントIDと秘密鍵(シークレットキー)の取得
まず初めに、Twitter、Facebook、Googleの管理画面から、クライアントIDとシークレットキーを取得します。
アプリケーションによってクライアントIDやシークレットキーの呼び名は多少異なります。
Twitterの場合は、コンシューマーキーとコンシューマーシークレットと呼びますが、ほぼ同じ意味なので推測できるでしょう。
Twitterの場合は、 https://apps.twitter.com/ から「Create New App」を押して、アプリケーションを作成します。
アプリケーションの設定を行います。
コールバックのURLは、https://localhost/auth/login/callback/twitter のように指定します。
「Keys and Access Tokes」というタブから、Consumer Key (API Key)とConsumer Secret (API Secret)を取得します。
Facebookの場合は、https://developers.facebook.com/apps/ から「新しいアプリを追加」を押して、新しいアプリケーションを追加します。
アプリケーションの設定を行います。
コールバックのURLは、https://localhost/auth/login/callback/facebook のように指定します。
「アプリID」と「app secret」の値を取得します。
Googleの場合、https://console.developers.google.com/apis/library から、プロジェクトを作成します。
コールバックのURLは、https://localhost/auth/login/callback/google のように指定します。
「クライアントID」と「クライアントシークレット」を取得します。
また、必ず、Google+ APIを有効にしておきます。
これを有効にしておかないと「クライアントID」と「クライアントシークレット」を取得しても、正しくソーシャルログインできません。
エラーになってしまいます。
Laravelでソーシャル認証の実装
それでは、ソーシャルログインを実装していきましょう。
まず、.envに以下のように記述しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#Facebook FACEBOOK_ID=aaa FACEBOOK_SECRET=bbb FACEBOOK_CALLBACKURL=https://localhost/auth/login/callback/facebook #Twitter TWITTER_ID=ccc TWITTER_SECRET=ddd TWITTER_CALLBACKURL=https://localhost/auth/login/callback/twitter #Google GOOGLE_ID=eee GOOGLE_SECRET=fff GOOGLE_CALLBACKURL=https://localhost/auth/login/callback/google |
ちなみに、この例ではlocahostを使っていますが、Googleはlocalhostではテストできません。
Googleの場合、必ず、グローバルに解決できるURLである必要があります。
TwitterとFacebookはlocalhostでテスト出来ました。
次に、config/services.php に以下を追加しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
'twitter' => [ 'client_id' => env('TWITTER_ID'), 'client_secret' => env('TWITTER_SECRET'), 'redirect' => env('TWITTER_CALLBACKURL'), ], 'facebook' => [ 'client_id' => env('FACEBOOK_ID'), 'client_secret' => env('FACEBOOK_SECRET'), 'redirect' => env('FACEBOOK_CALLBACKURL'), ], 'google' => [ 'client_id' => env('GOOGLE_ID'), 'client_secret' => env('GOOGLE_SECRET'), 'redirect' => env('GOOGLE_CALLBACKURL'), ], |
次に、routes.php に以下を追加しておきます。
1 2 3 4 5 6 7 8 9 10 11 |
//Twitter Route::get('auth/login/twitter', 'Auth\SocialController@getTwitterAuth'); Route::get('auth/login/callback/twitter', 'Auth\SocialController@getTwitterAuthCallback'); //Facebook Route::get('auth/login/facebook', 'Auth\SocialController@getFacebookAuth'); Route::get('auth/login/callback/facebook', 'Auth\SocialController@getFacebookAuthCallback'); //Google Route::get('auth/login/google', 'Auth\SocialController@getGoogleAuth'); Route::get('auth/login/callback/google', 'Auth\SocialController@getGoogleAuthCallback'); |
このルーティングがちゃんと機能しているかどうかは、以下のコマンドで確認しておきます。
念のために、キャッシュをクリアしておきます。
# php artisan route:cache
ルーティングの一覧を表示します。
# php artisan route:list
routes.php に追加したルーティングが表示されれば、OKです。
次に、Controllers\Auth\SocialController.php を実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
public function getTwitterAuth() { return Socialite::driver('twitter')->redirect(); } public function getTwitterAuthCallback() { try { $tuser = Socialite::driver('twitter')->user(); } catch (\Exception $e) { return redirect("/"); } if ($tuser) { dd($tuser); } else { return 'something went wrong'; } } public function getFacebookAuth() { return Socialite::driver('facebook')->redirect(); } public function getFacebookAuthCallback() { try { $fuser = Socialite::driver('facebook')->user(); } catch (\Exception $e) { return redirect("/"); } if ($fuser) { dd($fuser); } else { return 'something went wrong'; } } public function getGoogleAuth() { return Socialite::driver('google')->redirect(); } public function getGoogleAuthCallback() { try { $guser = Socialite::driver('google')->user(); } catch (\Exception $e) { return redirect("/"); } if ($guser) { dd($guser); } else { return 'something went wrong'; } } } |
こんな感じでOKです。
Bootstrap用のソーシャルボタンとFont Awesome
UIとしては、ソーシャルボタンとFont Awesomeを使います。
views/auth/login.blade.php に以下を記述しておきます。
1 2 3 4 5 6 7 8 9 |
<a class="btn btn-block btn-social btn-twitter" href="login/twitter"> <span class="fa fa-twitter"></span> Sign in with Twitter </a> <a class="btn btn-block btn-social btn-facebook" href="login/facebook"> <span class="fa fa-facebook"></span> Sign in with Facebook </a> <a class="btn btn-block btn-social btn-google" href="login/google"> <span class="fa fa-google"></span> Sign in with Google </a> |
このように書いておくと、それらしいボタンが作成されます。
いざ、ソーシャルログイン
それでは、Twitter、Facebook、Googleを使ってログインしてみます。
初回ログイン時には、以下の記事に示したメッセージが表示されます。
それぞれ、ログインしてみました。
Twitterの場合、以下のように表示されます。
注意点として、Twitterではメールアドレスの取得は出来ません。
Twitterの中の人が以下のフォーラムで答えています。
How to get email from twitter user using OAuthTokens
The API won't return an email address to you. If you're interested in a user's email address, you'll have to ask the user for it within your own application as a completely distinct act.
Facebookの場合は以下のように表示されます。
Google+の場合は以下のように表示されます。
実際のプログラムでは以下のようにして、Id、Nickname、Name、Email、Avatarを取得します。
1 2 3 4 5 6 7 |
$user = Socialite::driver('facebook')->user(); $user->getId(); $user->getNickname(); $user->getName(); $user->getEmail(); $user->getAvatar(); |
ログイン後のURLにFacebookでは「#_=_」、Google+では「#」がついてしまう
ログイン認証そのものは問題なくできて、ログインできるようになりました。
ただ、Twitterでは問題ないものの、Facebook認証のコールバックのURLには「#_=_」、Google+認証のコールバックのURLには「#」がついてしまいます。
こんな感じです。
Facebook認証でログイン後のURL
1 |
http://hoge.hoge/#_=# |
Google+で認証後のログイン後のURL
1 |
http://hoge.hoge/# |
この件、いろいろと問題として指摘されているようです。
バグなのか仕様なのかよくわかりませんが、JavaScriptで修正を試みることとします。
以下のコードを入れました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
$(document).ready(function () { // Facebook/Googleの認証後のリダイレクト画面を修正 if (window.location.hash && window.location.hash == '#_=_') { if (window.history && history.pushState) { window.history.pushState("", document.title, window.location.pathname); } else { // Prevent scrolling by storing the page's current scroll offset var scroll = { top: document.body.scrollTop, left: document.body.scrollLeft }; window.location.hash = ''; // Restore the scroll offset, should be flicker free document.body.scrollTop = scroll.top; document.body.scrollLeft = scroll.left; } } // Googleの認証後のリダイレクト画面を修正 if (window.location.href[window.location.href.length - 1] === '#' && // for just the error url (origin + /#) (window.location.href.length - window.location.origin.length) === 2) { window.location.href = window.location.origin + ''; } }); |
なんかイマイチ納得できませんが、これでログイン後のURLに余分なものが付かなくなりました。
まとめ
ソーシャルログインが出来るとユーザーにとって、簡単にログイン出来るWEBサイトを作成することが出来ます。
「ユーザーがアカウント登録する」ことって結構な精神的な負担になるので、これらのログイン方法を用意すると多くのユーザーにログインしてもらいやすくなるでしょう。
LaravelはVersion 5になって飛躍的に普及し始めました。
日本語による解説書も出て来ましたね。
最後まで読んでいただきありがとうござました。
この記事が気に入っていただけたらシェアしてくれると嬉しいです。
コメント
[…] […]