【Laravel】Laravel SocialiteでGoogleログインを実装

本記事では、Laravel SocialiteでGoogleログインを実装する方法について紹介しています。

環境

PHP 8 Laravel 10 npm 9 node 20 OS mac

動作イメージ

  1. Googleのログインボタンを押す
  2. LoginWithGoogleControllerでGoogleの認証画面にリダイレクト
  3. 認証成功したら、LoginWithGoogleControllerで指定したルート(auth/google/callback)へリダイレクト
  4. auth/google/callbackに来たら、LoginWithGoogleControllerのhandleGoogleCallback()でユーザを新規作成してDBへ登録
  5. 登録完了後にダッシュボード画面にリダイレクト

設定手順

  1. Laravel Breezeをインストール
composer require laravel/breeze
php artisan migrate
php artisan breeze:install blade
npm install & npm run dev

  1. Socialiteをインストール
composer require laravel/socialite
npm install && npm run dev
php artisan migrate
  1. APIとサービスのメニューから認証情報を作成

  2. OAuth クライアント ID の作成を選択

  3. 認証情報を取得する。URIをそれぞれ(認証リクエスト送信元・送信先)設定

  4. .envの変更

GOOGLE_KEY="xxxxxxxxxx"
GOOGLE_SECRET="xxxxxxxxxx" 
GOOGLE_REDIRECT_URI="http://localhost:8000/auth/google/callback"
  1. services.phpの変更
'google' => [
  'client_id' => env('GOOGLE_KEY'), 
  'client_secret' => env('GOOGLE_SECRET'), 
  'redirect' => env('GOOGLE_REDIRECT_URI'), 
],
  1. ユーザーテーブルにgoogle_idカラムを追加
php artisan make:migration add_google_id_to_users_table
<?php


use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;


class AddGoogleIdToUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table("users", function (Blueprint $table) {
            // 追加
            $table->string("google_id")->nullable();
        });
    }


    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table("users", function (Blueprint $table) {
            // 追加
            $table->dropColumn('google_id');
        });
    }
}
  1. マイグレーションの実施
php artisan migrate
  1. Userモデルのホワイトリストgoogle_idを追加
 protected $fillable = [
        "name",
        "email",
        "password",
        // 追加
        "google_id",
 ];
  1. ルーティング設定
<?php 
// 追加
use App\Http\Controllers\LoginWithGoogleController;

// 追加
Route::get("auth/google", [
  LoginWithGoogleController::class,
  "redirectToGoogle",
]);

// 追加
Route::get("auth/google/callback", [
  LoginWithGoogleController::class,
  "handleGoogleCallback",
]);
  1. コントローラの作成
php artisan make:controller LoginWithGoogleController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

// 追加
use Laravel\Socialite\Facades\Socialite;
// 追加
use App\Models\User;
// 追加
use Illuminate\Support\Facades\Auth;
// 追加
use Exception;

class LoginWithGoogleController extends Controller
{
    // 追加
    public function redirectToGoogle()
    {
        return Socialite::driver("google")->redirect();
    }

    // 追加
    public function handleGoogleCallback()
    {
        try {
            $user = Socialite::driver("google")->user();
            $finduser = User::where("google_id", $user->id)->first();

            if ($finduser) {
                Auth::login($finduser);
                return redirect()->intended("dashboard");
            } else {
                $newUser = User::create([
                    "name" => $user->name,
                    "email" => $user->email,
                    "google_id" => $user->id,
                    "password" => encrypt("123456dummy"),
                ]);

                Auth::login($newUser);

                return redirect()->intended("dashboard");
            }
        } catch (Exception $e) {
            \Log::error($e);
            throw $e->getMessage();
        }
    }
}
  1. ログイン画面にGoogleのログインボタン追加 resources\views\auth\login.blade.php
<div class="flex items-center justify-end mt-4">
  <a href="{{ url('auth/google') }}">
    <img src="https://developers.google.com/identity/images/btn_google_signin_dark_normal_web.png" style="margin-left: 3em;">
  </a>
</div>