本稿はLaravelのソーシャルログインの実装に関する記事です。
Socialiteのインストール
|
composer require laravel/socialite
|
config/app.phpの設定
「providers」と「aliases」に以下の記述を追記する。
|
'providers' => [
Laravel\Socialite\SocialiteServiceProvider::class,
],
'aliases' => [
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
],
|
.envの設定
独自のSNSのkey情報などを記載する。
※各SNSでのkeyの取得やコールバックURLの設定に関しては他の記事を参照してください。
Google OAuthはこちらを参照。
各SNSのコールバックURLは以下の通りにして下さい。
https://~.com/social/callback/google
https://~.com/social/callback/twitter
|
GOOGLE_CLIENT_ID="..."
GOOGLE_CLIENT_SECRET="..."
GOOGLE_CALLBACKURL="https://~.com/social/callback/google"
TWITTER_KEY="..."
TWITTER_SECRET="..."
TWITTER_CALLBACKURL="https://~.com/social/callback/twitter"
SESSION_DOMAIN=~.com
|
SESSION_DOMAINを記述しておかないと、callback url 呼び出し時に「Laravel\Socialite\Two\InvalidStateException」が発生します。
config/service.phpの設定
先ほど.envに設定した値を使用する。
|
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_CALLBACKURL'),
],
'twitter' => [
'client_id' => env('TWITTER_KEY'),
'client_secret' => env('TWITTER_SECRET'),
'redirect' => env('TWITTER_CALLBACKURL'),
],
|
Usersテーブルの定義変更
ソーシャルログインの場合、emailとpasswordカラムを使用しないのでnot null制約を外す必要がある。
migration機能もしくは直接修正すればよい。
migrationを使用する場合は以下のパッケージをインストールする必要があるので注意。
|
composer require doctrine/dbal
|
ルート設定
web.appに以下の記述を追記する。
|
Route::get('social/login/{provider}','SocialLoginController@login');
Route::get('social/callback/{provider}','SocialLoginController@callback');
|
コントローラーの作成
「App\Http\Controllers\Auth\SocialLoginController」を作成する。
|
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Log;
use Socialite;
class SocialLoginController extends Controller
{
public function login($provider)
{
return Socialite::driver($provider)->redirect();
}
public function callback($provider)
{
switch ($provider) {
case "google":
$socialUser = Socialite::driver($provider)->stateless()->user();
break;
case "twitter":
$socialUser = Socialite::driver($provider)->user();
break;
}
log::info(var_export($socialUser, true));
...後続処理
}
}
|
Googleの場合、statelessを指定しないとInvalidStateExceptionが発生する場合があります。
「log::info(var_export($socialUser, true))」の部分でレスポンスを確認できます。
あとはIDを見て存在すればログイン処理、存在しなければユーザ登録処理などに繋ぎましょう。
ID管理にuserテーブルにgoogle_idやtwitter_idカラムを追加するのもありです。
ログイン処理およびユーザー新規登録の実装例
以下、実装例を記載します。
userテーブルにgoogle_idおよびtwitter_idカラムを追加します。適当にvarchar(300)ほどで追加しましょう。nullを許容することを忘れずに。
続けて、コントローラーを以下の様に書き換えます。
|
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\User;
use DB;
use Log;
use Socialite;
class SocialLoginController extends Controller
{
public function login($provider)
{
return Socialite::driver($provider)->redirect();
}
public function callback($provider)
{
try {
/*
* プロバイダーからユーザー情報取得
*/
switch ($provider) {
case "google":
$socialUser = Socialite::driver($provider)->stateless()->user();
break;
case "twitter":
$socialUser = Socialite::driver($provider)->user();
break;
}
$socialUserId = $socialUser->getId();
$socialUserName = $socialUser->getName();
$socialUserEmail = $socialUser->getEmail();
/*
* ユーザー情報の取得
*/
switch ($provider) {
case "google":
$user = DB::table('users')->where('google_id', $socialUserId)->first();
break;
case "twitter":
$user = DB::table('users')->where('twitter_id', $socialUserId)->first();
break;
}
if(empty($user)){
log::info("New SocialUser Registration Start");
/*
* ユーザー登録処理
*/
switch ($provider) {
case "google":
$user = User::create([
'name' => $socialUserName,
'email' => $socialUserEmail,
'google_id' => $socialUserId,
]);
break;
case "twitter":
$user = User::create([
'name' => $socialUserName,
'email' => $socialUserEmail,
'twitter_id' => $socialUserId,
]);
break;
}
}else{
$user = User::find($user->id);
}
/*
* ログイン処理
*/
auth()->login($user, true);
return redirect("/");
} catch (Exception $e) {
return redirect("/");
}
}
}
|