見出し画像

LaravelでSocialiteを利用しFacebookログインを実装する方法

LaravelでSocialiteを利用しFacebookログインを実装する方法を記載します。

前提

前提として、下記のnoteを参考にSocialiteを利用しtwitterログインができるようにしておいてください。SocialiteのLaravelへの導入等はこちらの記事で行なっています。

それでは始めます。


Facebook for Developersにアプリ登録をする

Facebook for Developersにアプリ登録を行います。Facebookにログインした状態で下記にアクセスします。

「新しいアプリを追加」をクリックします。

スクリーンショット 2019-09-25 9.13.11

「表示名」にアプリの名前を記入し「アプリIDを作成してください」をクリックします。

スクリーンショット 2019-09-25 9.15.05

セキュリティチェックをして「送信する」をクリックします。

スクリーンショット 2019-09-25 9.16.51

「製品を追加」より「Facebookログイン」を追加します。

スクリーンショット 2019-09-25 9.18.18

以上でアプリ登録が完了です。


アプリID、app secretの確認

作成したアプリの「アプリID」と「app secret」を確認します。

Facebook for Developersの左サイドバー「設定」→「ベーシック」をクリックし、設定画面内の「アプリID」と「app secret」をメモしておいてください。

スクリーンショット 2019-09-26 12.37.00

プライバシーポリシー、利用規約の記載

また、同じページ内の「プライバシーポリシーのURL」「利用規約のURL」には、それぞれサイトのプライバシーポリシーと利用規約のページURLを記載します。記載したら画面右下の「変更を保存」をクリックします。

スクリーンショット 2019-09-26 13.35.50


有効なOAuthリダイレクトURIの記載

次に、左メニューより「Facebookログイン」→「設定」をクリックし、「有効なOAuthリダイレクトURI」にコールバックURLを記載し、「変更を保存」をクリックします。

今回は「https://・・・/login/facebook/callback」と記載しました
(・・・の部分はご自分のURLを記載ください)

また、「有効なOAuthリダイレクトURI」もコピーしておいてください。

スクリーンショット 2019-09-25 9.50.37

.envファイルを修正

Laravelの.envファイルに下記追記します。上記でコピーした内容を記載します。

FACEBOOK_APP_ID=FacebookのアプリID
FACEBOOK_APP_SECRET=FacebookのシークレットID
FACEBOOK_CALLBACK_URL=有効なOAuthリダイレクトURI


テーブルの修正

現在利用しているuserテーブルにfacebook用のフィールドを追加します。
現在は下記のように制作しておりますので、

$table->increments('id');
          $table->string('name');
          $table->string('email')->unique();
          $table->timestamp('email_verified_at')->nullable();
          $table->string('password')->nullable();
          $table->string('avatar')->nullable()->unique();
          $table->string('twitter_id')->nullable()->unique();
          $table->rememberToken();
          $table->timestamps();

ここにfacebook idを格納するフィールドを追加します。

$table->increments('id');
          $table->string('name');
          $table->string('email')->unique();
          $table->timestamp('email_verified_at')->nullable();
          $table->string('password')->nullable();
          $table->string('avatar')->nullable()->unique();
          $table->string('twitter_id')->nullable()->unique();
          $table->string('facebook_id')->nullable()->unique();
          $table->rememberToken();
          $table->timestamps();
↑『$table->string('facebook_id')->nullable()->unique(); 』を追加しました。

こちらでmigrationを行い、フィールドを追加します。


web.phpの修正

web.phpにfacebookログインを追加します。下記に修正します。

Route::get('/login/{social}', 'Auth\OAuthLoginController@socialLogin');
Route::get('/login/{social}/callback', 'Auth\OAuthLoginController@handleProviderCallback');
※twitterログインの場合はtwitterログインのみの想定で作成してましたが、今回は「twitter」「Facebook」を2種類のログインを想定します。


config/services.php の修正

下記追記します。

    'facebook' => [
       'client_id'     => env('FACEBOOK_APP_ID'),
       'client_secret' => env('FACEBOOK_APP_SECRET'),
       'redirect'      => env('FACEBOOK_CALLBACK_URL')
   ],


OAuthLoginController.php の修正

次にコントローラーを修正します。

前回のsocialiteを利用してのtwitterログインの場合はtwitterだけの想定でしたが、今回は「twitter」と「Facebook」の2種類でのログイン対応します。
また、今後他のソーシャルアカウントでもログインしたい場合に柔軟に対応できるようにコードを修正します。

class OAuthLoginController extends Controller
{
   public function socialLogin($social)
   {
       return Socialite::driver($social)->redirect();
   }
   //Callback処理
   public function handleProviderCallback($social)
   {
       // ユーザ属性を取得
       try {
           $userSocial = Socialite::driver($social)->user();
       } catch (Exception $e) {
           // OAuthによるユーザー情報取得失敗
           return redirect()->route('/')->withErrors('ユーザー情報の取得に失敗しました。');
       }
       //メールアドレスで登録状況を調べる
       $user = User::where(['email' => $userSocial->getEmail()])->first();
      
       //メールアドレス登録の有無で条件分岐
       if($user){
           //email登録がある場合の処理            
           //ログイン
           Auth::login($user);
       }else{
           //メールアドレスがなければユーザ登録
           $newuser = new User;
           $newuser->name = $userSocial->getName();
           $newuser->email = $userSocial->getEmail();
       
           // 画像の取得
           $img = file_get_contents($userSocial->avatar_original);
           if ($img !== false) {
               $file_name = $userSocial->id . '_' . uniqid() . '.jpg';
               Storage::put('public/profile_images/' . $file_name, $img);
               $newuser->avatar = $file_name;
           }
           //sns特有の情報を条件分岐で取得する
           switch ($social) {
               case "facebook":
                   $newuser->facebook_id = $userSocial->getNickname();
                   $newuser->facebook_unique_id = $userSocial->getId();
               case "twitter":
                   $newuser->twitter_id = $userSocial->getNickname();
                   $newuser->twitter_unique_id = $userSocial->getId();
               break;
           }
           //ユーザ作成     
           $newuser->save();
           //ログイン
           Auth::login($newuser);
       }
       //topページにリダイレクト
       return redirect('/'); 
   }
}


Viewの修正

facebookログインリンクをviewに記載します。ログインリンクを表示させたいbladeファイルに下記追記します。

<a href="{{ url('login/facebook')}}">Facebookログイン)</a>

こちらのリンクをクリックすると下記のような画面が表示され

スクリーンショット 2019-09-26 12.48.30

「〇〇としてログイン」をクリックするとログインできるようになります。

以上で対応完了です。


追記:ログイン後リダイレクトのURLに「#_=_」という文字がついてしまう。

これまでの説明でFacebookログインの対応は完了なのですが、いざログインしてみると、ログイン後のURLの最後に#_=_」という文字がついてしまう現象が起きてしまいます。下記のような状態です。

http://localhost/#_=_

調べてみると、色々と議論されているようでした。

根本的な解決策はないようで、みなさんJavascriptを書いて解決しているようでしたので、こちらでもJavascriptを書いて解決します。

上記stackoverflowのベストアンサーの下記記述を、bladeファイルに追記します。

<script type="text/javascript">
   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;
       }
   }
</script>

これで「#_=_」という文字がURLに付かなくなりました。


以上です。


※何か間違いや修正がある場合はコメントかtwtterのDMにてご連絡いただけますと嬉しいです!


参考

下記記事を参考にさせていただきました。ありがとうございました!


読んでいただきありがとうございます。