Skip to content

Instantly share code, notes, and snippets.

@ishikawam
Last active December 14, 2020 23:59
Show Gist options
  • Save ishikawam/b02cc7d9a0616022ff1b962112e0b7b4 to your computer and use it in GitHub Desktop.
Save ishikawam/b02cc7d9a0616022ff1b962112e0b7b4 to your computer and use it in GitHub Desktop.
/**
* オレが考えたSocialiteのサンプルコード(いまのところ)
*/
// Social Login
Route::prefix('login/{provider}')->where(['provider' => '(facebook|twitter|github|line)'])->group(function () {
Route::get('/', [App\Http\Controllers\Auth\LoginController::class, 'redirectToProvider'])->name('login.redirect');
Route::get('/callback', [App\Http\Controllers\Auth\LoginController::class, 'handleProviderCallback'])->name('login.callback');
});
/////
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite;
class LoginController extends Controller
{
/**
* redirectToProvider
*/
public function redirectToProvider(Request $request)
{
$provider = $request->provider;
return Socialite::driver($provider)->redirect();
}
/**
* handleProviderCallback
*/
public function handleProviderCallback(string $provider)
{
try {
$providerUser = Socialite::with($provider)->user();
} catch(\Laravel\Socialite\Two\InvalidStateException $e) {
// callbackの間が空いたらなる?
\Log::warning(get_class($e));
return redirect('/login')->withErrors('ログインできませんでした');
} catch(\GuzzleHttp\Exception\ClientException $e) {
// 二重callback
\Log::warning(get_class($e));
return redirect('/login')->withErrors('ログインできませんでした');
} catch(\Exception $e) {
\Log::error(get_class($e));
return redirect('/login')->withErrors(['ログインできませんでした', get_class($e)]);
}
$user = $this->firstOrCreateUser($providerUser, $provider);
\Auth::login($user, true);
return redirect('/dashboard');
}
/**
* firstOrCreateUser
*
* @param \Laravel\Socialite\Contracts\User $providerUser
* @param string $provider
* @return \App\Models\User
*/
private function firstOrCreateUser(\Laravel\Socialite\Contracts\User $providerUser, string $provider): User
{
$socialAccount = \App\Models\SocialAccount::where([
'provider' => $provider,
'provider_user_id' => $providerUser->getId(),
])
->first();
if ($socialAccount) {
return $socialAccount->user;
}
// userと取得したemailが一致したらアカウント連携する
$email = $providerUser->getEmail();
$user = User::where('email', $email)->first();
if ($email && $user) {
$user->SocialAccount()->create([
'provider' => $provider,
'provider_user_id' => $providerUser->getId(),
]);
return $user;
}
// ユーザー作成
$user = User::create([
'email' => $email,
'name' => $providerUser->getNickname() ?: $providerUser->getName(),
]);
$user->SocialAccount()->create([
'provider' => $provider,
'provider_user_id' => $providerUser->getId(),
]);
return $user;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment