2018/10/12
前回、ソーシャルログインの簡易版を作成しました。
認証後の画面でLaravelのヘルパ関数dd()でGitHubアカウント情報を表示しました。
今回は認証後、DBにアカウント情報を入れる仕組みを追加します。
手順
【1】ソーシャルログイン情報のTABLE作成
【2】モデルの編集
【3】コントローラの編集
【4】動作確認
【1】ソーシャルログイン情報のTABLE作成
認証用のTABLEは以前に作成しました。(※usersテーブル)
これとは別にソーシャルログイン情報のテーブル(social_providers)を用意します。
まずはソーシャルログイン情報のテーブルとモデルを作成します。
php artisan make:model -m SocialProvider
make:modelコマンドに--migrationか-mオプションをつけるとマイグレーションファイルも同時に作成されます。
次にartisanコマンドで生成されたマイグレーションファイルのスケルトンを編集します。
テーブルのスキームを作成します。
: public function up() { Schema::create('social_providers', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id')->unsigned()->references('id')->on('users'); $table->string('provider_id'); $table->string('provider'); $table->timestamps(); }); } :
編集したマイグレーションファイルを反映させます。
php artisan migrate
social_providersテーブルができているか確認。
【2】モデルの編集
usersテーブルとsocial_providersテーブルをモデルで紐付けしておきます。
この作業をしておくと、JOIN句を使わなくても結合してテーブルを表示させることができます。
また認証後、usersテーブルとsocial_providersテーブルの両方に値を挿入するのですが、楽に記述できます。
まず、ソーシャルログインで利用するテーブルについて確認します。
テーブルについて
social_providersテーブル(ソーシャルプロバイダー)・・・SNSのアカウントの種類
次にusersテーブルとsocial_providersテーブルの関係性についてみてみます。
まず、仕様ですがユーザーは複数のSNSアカウントでログインができるようにします。
例えばAさんが GitHub でログインできたり Facebook や Twitter でもログインできるようにします。
こう考えるとusersテーブルとsocial_providersテーブルの関係は 1:多 の関係であると理解できます。
Userモデル
ユーザーは複数のSNSアカウントでログインできる。
↓
"ユーザー" hasMany "ソーシャルプロバイダー" の関係
よって、userモデルは以下の記述をします。
: function socialProviders() { return $this->hasMany(SocialProvider::class); } :
SocialProviderモデル
次にソーシャル用のモデルを編集します。
ソーシャルプロバイダーのテーブルではレコードごとに必ずユーザー情報が入ります。
↓
見方を変えるとソーシャルプロバイダーはユーザーに所属することになります。
↓
"ソーシャルプロバイダー" belongs to "ユーザー" の関係
: protected $fillable = ['provider_id','provider']; //登録できる項目を宣言 function user() { return $this->belongsTo(User::class); } :
【3】コントローラの編集
冒頭でソーシャル用のモデル(SocialProvider)をuseしておきます。
: use App\SocialProvider; :
認証後の処理をしていた handleProviderCallback() を修正します。
: public function handleProviderCallback() { try { $socialUser = Socialite::driver('github')->user(); } catch(Exception $e) { return redirect('/'); } //すでに登録済みかチェック $socialProvider = SocialProvider::where('provider_id',$socialUser->getId())->first(); if(!$socialProvider) { //レコードの作成+データの挿入 $user = User::firstOrCreate( ['email' => $socialUser->getEmail(), 'name' => $socialUser->getName()] ); //ソーシャルプロバイダーのテーブルにレコードを追加 $user->socialProviders()->create( ['provider_id' => $socialUser->getId(), 'provider' => 'github'] ); } else $user = $socialProvider->user; auth()->login($user); return redirect('user/profile'); }
Socialiteのver2ではGitHubアカウントのemailはバグで取得できません。
usersテーブルのemailのカラムはnullでも問題ないように変更しておきます。
SNSアカウント情報のパスワードは取得することはできません。
【4】動作確認
GitHubでログインをしてレコードがDBに挿入されているか確認します。
usersテーブル
social_providersテーブル
以上のようにレコードが挿入されていればOKです。
仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら。