Masayan tech blog.

  1. ブログ記事一覧>
  2. 【Lavavel】Laravel SocialiteでGoogleログインを実装する

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

公開日

前置き

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

Laravelプロジェクトの作成までは完了している前提です。

環境

  • windows10
  • Laravel 8.54
  • PHP 8.0.10
  • node v14.17.6
  • npm 6.14.15
  • VsCode

動作イメージ

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

Laravel Jetstream

laravel UI

設定手順

Dockerでlaravelプロジェクトを作成するところまでは完了している前提です。

Laravelコンテナに入る

docker exec -it app-dl bash

認証パッケージのインストール

Laravel Jetstream場合

JetStream
root@c869fe52d641:/var/www/my-app# composer require laravel/jetstream
LiveWire
root@c869fe52d641:/var/www/my-app# php artisan jetstream:install livewire

laravel UIの場合

root@c869fe52d641:/var/www/my-app# composer require laravel/uiroot@c869fe52d641:/var/www/my-app# php artisan ui vue --auth

Socialiteをインストール

root@c869fe52d641:/var/www/my-app# composer require laravel/socialite

※公式ドキュメントを見ると、Laravel 5.4以前は以下の設定も必要な様子です。

config/app.php設定ファイルへLaravel\Socialite\SocialiteServiceProviderを登録

'providers' => [
  Laravel\Socialite\SocialiteServiceProvider::class,
],

aliases配列にSocialiteファサードを追加します。

'aliases' => [
  'Socialite' => Laravel\Socialite\Facades\Socialite::class,
]

パッケージインストール&ビルド

root@c869fe52d641:/var/www/my-app# npm install && npm run dev

マイグレーション

root@c869fe52d641:/var/www/my-app# php artisan migrate

ここまでで、ウェルカム画面にログインのリンクが追加されます。

ソーシャルメディアの認証情報の準備

  • クライアントID とシークレットキーの取得。
  • コールバックURLの設定(アプリ側に返すURLを指定)。

Googleの場合

GCPで新しくプロジェクトを作成し、APIとサービスのメニューから認証情報を作成

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

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

設定ファイル

先ほどの認証情報を.envに記述し、それをservices.phpに設定する

.env

GOOGLE_KEY="xxxxxxxxxx"
GOOGLE_SECRET="xxxxxxxxxx" 
GOOGLE_REDIRECT_URI="http://localhost:8500/auth/google/callback"

config/services.php

'google' => [
  'client_id' => env('GOOGLE_KEY'), 
  'client_secret' => env('GOOGLE_SECRET'), 
  'redirect' => env('GOOGLE_REDIRECT_URI'), 
],

ユーザーテーブルにgoogle_idカラムを追加

root@c869fe52d641:/var/www/my-app# php artisan make:migration add_google_id_to_users_table

my-app\database\migrations\2021_09_18_042801_add_google_id_to_users_table.php

<?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');
        });
    }
}

マイグレーション

root@c869fe52d641:/var/www/my-app# php artisan migrate

Userモデルのホワイトリストにgoogle_idを追加

   my-app\app\Models\User.php

 protected $fillable = [
        "name",
        "email",
        "password",
        // 追加
        "google_id",
 ];

ルーティング設定

アプリ側からGoogleログインボタンを押したときの遷移先と、認証後のアプリ側のリダイレクト先ルーティングを設定する

my-app\routes\web.php

<?php 
// 追加
use App\Http\Controllers\LoginWithGoogleController;

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

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

コントローラー作成

root@c869fe52d641:/var/www/my-app# php artisan make:controller LoginWithGoogleController

my-app\app\Http\Controllers\LoginWithGoogleController.php

<?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();
        }
    }
}

ログイン画面にGoogleのログインボタン追加

my-app\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>

以上で設定完了です。ログイン画面のGoogleログインボタンを押すと、見慣れたGoogle認証画面が表示されるはずです。

おまけ:Laravelの主な認証スカフォールド

  • Laravel Breeze
    Tailwind CSS && Blade Templates で構成
  • Laravel Jetstream
    Tailwind CSS && (Livewire || Inertia) で構成
     Fortify、Sanctum
  • Passport
    OAuth 2 プロバイダ実装
  • Socialite
    OAuth 2 ログイン実装
  • laravel UI
    Bootstrap && (React || Vue) で構成

まとめ

いかがでしたでしょうか。本記事では、Laravel SocialiteでGoogleログインを実装する方法について紹介しています。GCP側でクライアントIDとシークレットキーの取得が必要ですが、設定自体はシンプルで難しくはないので、ぜひ参考にして実装してみてください。