Windowsのローカル環境でLaravelのGoogleログインを実装してみた話

# はじめに
最近はかなりのサイトで採用されているソーシャルログインですが、自分で実装したことがなかったので、調査のために環境構築から動作確認までやってみた備忘録です。
キャプチャを残してないので文字ばかりなのはご容赦ください。
バージョンは2023年9月当時のものとなります。
コマンドの実行は基本的にコマンドプロンプトでやっていますが、PowerShellでも問題ないはずです。
# 環境構築
## PHP
1. [PHP For Windows: Binaries and sources Releases](https://windows.php.net/download/)から「PHP 8.2 (8.2.9)＞VS16 x64 Thread Safe (2023-Aug-01 13:08:42)＞Zip」をダウンロード
2. 「C:\php」に解凍
3. 環境変数の「Path」に`C:\php`を追加
4. `php -v`を実行して`PHP 8.2.9`と表示されたらOK
## Composer
1. [Composer](https://getcomposer.org/download/)からComposer-Setup.exeをダウンロード＞実行してインストール（途中でDeveloper modeやProxyを聞かれるが、そのまま進む）
2. `composer -v`を実行して`Composer version 2.5.8`と表示されたらOK
## Laravel
1. 「C:\php\php.ini」をエディタなどで開いて、以下2行の先頭の「;」を削除（コメントアウトを外す）
    ```
    ;extension=fileinfo
    ;extension=zip
    ```
2. `composer global require laravel/installer`を実行
	インストール開始時に以下のようなメッセージが出る
	`Changed current directory to D:/Users/xxxx/AppData/Roaming/Composer`
3. 環境変数の「Path」に`D:\Users\xxxx\AppData\Roaming\Composer\vendor\bin`を追加（2で表示されたパスに\vendor\binを付けたもの）
4. `laravel -v`を実行して`Laravel Installer 5.1.0`と表示されたらOK
## MySQL（[MySQL 8 のインストール (Windows 版) - MySQL - ソーサリーフォース](https://sorceryforce.net/ja/tips/mysql-install8-windows)を参考にしました）
1. [MySQL :: Download MySQL Installer](https://dev.mysql.com/downloads/installer/)からバージョンは8.0.34、OSはWindowsを指定してダウンロード（2種類あるけどオンライン／オフラインインストールの違いなのでどちらでも）
	サインアップ画面が出るが無視して左下の「No thanks, just start my download.」というリンクからダウンロードする
2. ダウンロードしたmsiファイルを実行してインストール
	Setup TypeはFullを指定
	Account and Rolesでrootユーザのパスワードを任意に設定
	Connect To Serverでパスワードチェック（設定したパスワードで接続確認）を行う
	それ以外は変更せずにNext/Executeで進める
3. 環境変数の「Path」に`C:\Program Files\MySQL\MySQL Server 8.0\bin`を追加
4. `mysql --version`を実行して`mysql  Ver 8.0.34 for Win64 on x86_64`と表示されたらOK
## プロジェクト作成
1. `laravel new sociallogin`を実行（任意のプロジェクト名で）
	質問は以下のように回答する
    starter kit＞none
    testing framework＞1
    database＞mysql
2. `cd sociallogin`でプロジェクトフォルダに移動
3. `php artisan -v`を実行して`Laravel Framework 10.21.0`と表示されたらOK
## DB接続、migrate準備
1. プロジェクト内の以下のファイルを編集
	**.env**
		「DB_PASSWORD」にMySQLインストール時に設定したrootパスワードを記載
	**database\migrations\2014_10_12_000000_create_users_table.php**
		`$table->string('password');`を`$table->string('google_id');`に変更（パスワードログインはしない）
2. 「C:\php\php.ini」をエディタなどで開いて、`;extension=pdo_mysql`の先頭の「;」を削除
## 認証パッケージインストール、migrate実行
1. `cd sociallogin`でプロジェクトフォルダに移動
2. `composer require laravel/socialite`を実行（エラーが出ずに終了したらOK）
3. `php artisan migrate`を実行（データベースを作成するか聞かれるので、「yes」で進む）
4. `mysql -u root -p`を実行（パスワードを聞かれるのでrootパスワードを入力）
5. MySQLにログインできたら`use sociallogin;`を実行
6. `desc users;`を実行して、passwordカラムがなく、google_idカラムががあればOK
## SSL証明書設定（Googleからのリダイレクトがhttpsなので）
1. [curl](https://curl.se/)から「Documentation＞CA bundle＞cacert.pem」をダウンロードして任意の場所に置く
2. 「C:\php\php.ini」をエディタなどで開いて、`;curl.cainfo =`の先頭の「;」を削除し、cacert.pemをフルパスで記載
## Google Cloud Platform（以降は[Laravel SocialiteでGoogleログインを実現する](https://zenn.dev/naoki_oshiumi/articles/80ab178d958447)を参考にしました）
1. プロジェクトを作成
2. 「認証情報＞認証情報を作成＞OAuthクライアントID」を以下のように作成
	アプリケーションの種類：ウェブアプリケーション
	名前：任意
	承認済みJavaScript生成元：`http://localhost`
	承認済みのリダイレクトURI：`http://localhost/login/callback`
3. クライアントIDとクライアントシークレットが発行される（後で使うのでメモっておく）
# 実装
1. `cd sociallogin`でプロジェクトフォルダに移動
2. `php artisan make:controller GoogleLoginController`を実行してコントローラーを作成
3. プロジェクト内の以下のファイルを編集
	**.env**
    ```php
    GOOGLE_CLIENT_ID=Google Cloud Platformで発行されたもの
    GOOGLE_CLIENT_SECRET=Google Cloud Platformで発行されたもの
    GOOGLE_CALLBACK_URL=http://localhost/login/callback（Google Cloud Platformの承認済みのリダイレクトURIと合わせる）
    ```
	**config\services.php**
		末尾に以下を追記
    ```php
    'google' => [
    	'client_id' => env('GOOGLE_CLIENT_ID'),
    	'client_secret' => env('GOOGLE_CLIENT_SECRET'),
    	'redirect' => env('GOOGLE_CALLBACK_URL'),
    ],
    ```
	**routes\web.php**
		末尾に以下を追記（自動で作られていたルーティングは削除）
    ```php
    Route::get('/', [GoogleLoginController::class, 'getGoogleAuth']);
    Route::get('/login/callback', [GoogleLoginController::class, 'authGoogleCallback']);
    ```
	**app\Models\User.php**
		以下のように実装
    ```php
    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Foundation\Auth\User as Authenticatable;
    use Illuminate\Notifications\Notifiable;
    use Laravel\Sanctum\HasApiTokens;
    
    class User extends Authenticatable
    {
        use HasApiTokens, HasFactory, Notifiable;
    
        /**
         * The attributes that are mass assignable.
         *
         * @var array<int, string>
         */
        protected $fillable = [
            'name',
            'email',
            'email_verified_at',
            'google_id',
        ];
    
        /**
         * The attributes that should be hidden for serialization.
         *
         * @var array<int, string>
         */
        protected $hidden = [
            'remember_token',
        ];
    
        /**
         * The attributes that should be cast.
         *
         * @var array<string, string>
         */
        protected $casts = [
            'email_verified_at' => 'datetime',
        ];
    }
    ```

	**app\Http\Controllers\GoogleLoginController.php**
		以下のように実装
    ```php
    <?php
    
    namespace App\Http\Controllers;
    
    use App\Models\User;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Auth;
    use Laravel\Socialite\Facades\Socialite;
    
    class GoogleLoginController extends Controller
    {
        public function getGoogleAuth()
        {
            return Socialite::driver('google')->redirect();
        }
    
        public function authGoogleCallback()
        {
            $googleUser = Socialite::driver('google')->stateless()->user();
            $user = User::firstOrCreate([
                'email' => $googleUser->email
            ], [
                'email_verified_at' => now(),
                'name' => $googleUser->name,
                'google_id' => $googleUser->getId()
            ]);
            Auth::login($user, true);
            return view('welcome');
        }
    }
    ```
# 動作確認
1. `cd sociallogin`でプロジェクトフォルダに移動
2. `php artisan serve --port=80`でアプリを起動
3. `http://localhost`に接続するとGoogleアカウント選択画面が表示される
4. アカウントを選択するとログインが実行され、Laravelのウェルカムページが表示される
5. MySQLにログインしてusersテーブルにログインしたユーザーのメールアドレスその他が登録されていたらOK
# おわりに
環境構築～実装～動作確認のボリュームの尻すぼみ感がすごいですが、実際に設定さえできてしまえば、「Socialiteの機能を使ってGoogle認証に飛ばす＞認証できたら設定したリダイレクト先に飛ばす」だけという、お手軽な実装でソーシャルログインが動きました。
この後はログアウト処理を入れたり、サーバーに乗せて動かそうと考えているので、ネタが溜まったら続編を書くかもしれません。
ソーシャルログインを実装してみようと思っている方の参考になれば幸いです。
また、記事のために実際のコードとは少し変えている箇所があるので、間違いや動かないなどの指摘があればコメントお願いします。