Laravel Socialiteでちょっとだけ困ったのでカスタマイズした話 #laravel

f:id:akase244:20160829182344j:plain

最近、Bitcoin APIのマニュアルばかりを眺めている日々が続いている @akase244 です。(その話はまた別の機会にでも)

ところでみなさん、ソーシャルログインしてますか?しまくりですか?私は仕事中でもちょいちょいしてます。(秘密ですよ)

今回は、Laravelのとても便利なソーシャルログイン機能である「Laravel Socialite」のカスタマイズについて触れてみます。

使い方の基本パターン

Laravel Socialiteの使い方については公式ドキュメントの手順に沿うと特に迷うことはないかと思いますので、ここでは少しかけ足で説明します。

  1. composerでLaravel Socialiteをインストールする。
  2. app/config/app.php のprovidersとaliasesにLaravel Socialiteについて追加する。
  3. app/config/services.php にソーシャルログインのためのプロバイダーの接続情報(クライアントID、パスワード、コールバックURL)を追加する。
  4. AuthController.php などのログイン処理を受け持つクラスにソーシャルログインボタン押下時(redirectToProvider)とソーシャルログイン後のコールバック時(handleProviderCallback)のメソッドを追加する。
  5. routes.php にredirectToProvider、handleProviderCallbackのルーティングを追加する。

これでソーシャルログイン機能がササッとできあがります。実際やってみるととても簡単です。

Facebookログインでちょっと困った

ソーシャルログインするだけであれば前述の基本パターンで問題ありませんが、ログインした後にログインユーザーの名前を取得したくなるのが人情です。

しかし、以下のコードで$providerがfacebookの場合、 getName() の結果は Akase Tsuyoshi のようにアルファベットの値が返ってきてしまいます。

Facebookの氏名を漢字で登録している場合でも、Laravel Socialiteで getName() するとアルファベットを返すように実装されているようです。

f:id:akase244:20160824045933p:plain

なぜアルファベットを返すのか実装を覗いてみよう

では、具体的にLaravel Socialiteの実装を覗いてみましょう。

対象となるメソッドは laravel/socialite/src/Two/FacebookProvider.phpgetUserByToken です。

laravel/socialite/src/Two/FacebookProvider.php

FacebookのGraph APIのドキュメントに目を通すと、getUserByToken内の $meUrl に「locale=ja_JP」というパラメータを付与することで、漢字の氏名が取得できそうだということが分かります。

しかし、getUserByTokenを見てみると新たにパラメータを付与できるような作りになっていないためカスタマイズが必要そうだということが分かります。

Laravel Socialiteをカスタマイズしてみよう

まず laravel/socialite/src/Two/FacebookProvider.php を継承した app/Providers/FacebookProvider.php を作成し、 getUserByToken をオーバーライドします。getUserByTokenでは app/config/app.phplocaleja の場合に「locale=ja_JP」をセットするようにしてみましょう。

具体的には変数 $meUrl をセットする箇所で、 .((\App::getLocale() === 'ja') ? '&locale=ja_JP' : '') という処理を追加します。

app/Providers/FacebookProvider.php

次に laravel/socialite/src/SocialiteManager.php を継承した app/Socialite/SocialiteManager.php を作成し、 createFacebookDriver をオーバーライドします。createFacebookDriverでは↑で作成したFacebookProviderを返すようにします。

ここは難しいことは全然なく継承元のコードを丸々コピーしてパスを変更するだけですね。

app/Socialite/SocialiteManager.php

さらに laravel/socialite/src/SocialiteServiceProvider.php を継承した app/Socialite/SocialiteServiceProvider.php を作成し、 register をオーバーライドします。registerでは↑のSocialiteManagerを返すようにします。

app/Socialite/SocialiteServiceProvider.php

これで準備が整いました。最後の仕上げに app/config/app.php のprovidersをカスタマイズしたものに差し替えます。

修正前

Laravel\Socialite\SocialiteServiceProvider::class,

修正後

App\Socialite\SocialiteServiceProvider::class,

この状態でFacebookログインし、 getName() を呼び出すと結果が 赤瀬 剛 になりました。うまくいったようです。

まとめ

いかがだったでしたか?意外と簡単にソーシャルログインのカスタマイズができることがお分かりいただけたのではないでしょうか。

私自身、まだまだLaravelのサービスコンテナやサービスプロバイダを深く理解しているわけではないので、「Laravel リファレンス」を片手にあーでもないこーでもないと試しながら、著者の一人でもあり同僚でもある localdisk に毎日教えてもらいつつ、Laravel力を磨く日々を過ごしています。