0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

laravel socialiteでOauth認証機能を加える

Posted at

laravel socialiteでOauth機能を追加したのでその過程をまとめる

環境構築はsail

laravel/socialiteのインストール

compooser require laravel/socialite

次にconfig/services.phpにクライアントの設定をした

//グーグル認証のクライアント設定
    'google' => [
    'client_id' => env('GOOGLE_CLIENT_ID'),
    'client_secret' => env('GOOGLE_CLIENT_SECRET'),
    'redirect' => env('GOOGLE_REDIRECT_URI'),
    ],

また、googleのクライアントのキーを取らなければいけないためgoogle consoleからoauth同意画面で設定して、認証情報を追加した。
この時にリダイレクトURLを設定しておかないと認証することができなくなる。

次に認証機能をまとめるSocialiteコントローラーを作成した

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Laravel\Socialite\Facades\Socialite;

class SocialiteController extends Controller
{
    //認証のリダイレクト処理
    public function redirect($provider)
    {
        return Socialite::driver($provider)->redirect();
    }

    //認証のコールバック処理
    public function callback($provider)
    {
        $user = Socialite::driver($provider)->user();
        dd($user);
    }
}

web.phpにリダイレクト用のルーティングとコールバック用のルーティングも追加する

//Google認証のルーティング

Route::get('/redirect/{provider}', [SocialiteController::class, 'redirect']);
Route::get('/callback/{provider}', [SocialiteController::class, 'callback']);

次に現在のuserテーブルではpasswordカラムがあるがoauth認証だけの想定であればそもそも必要ないためpasswordカラムは消す

./vendor/bin/sail artisan make:migration remove_password_column_from_users_table --table=users

マイグレーションファイル

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('password');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('password')->nullable();
        });
    }
};

それと同時にuserテーブルにはprovider_idtokenを持てるようにしたかったため追加する

./vendor/bin/sail artisan make:migration add_provider_columns_to_users_table --table=users

マイグレーションファイル

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('provider')->nullable()->after('email');
            $table->string('provider_id')->nullable()->after('provider');
            $table->string('avatar')->nullable()->after('provider_id');
            $table->string('token')->nullable()->after('avatar');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('provider');
            $table->dropColumn('provider_id');
            $table->dropColumn('avatar');
            $table->dropColumn('token');
        });
    }
};

またコントローラーではDBを触る処理を書きたくなかったためApp/Servives/SocialiteUserControllerにサービスクラスを追加して以下のようにした

<?php

namespace App\Services;

use App\Models\User;

class SocialiteUserService
{
    //userが存在するか確認し、存在しない場合は新規作成するサービスクラス
    public function findOrCreateUser($providerUser,$provider)
    {
        return User::firstOrCreate(
            ['email' => $providerUser->getEmail()],
            [
                'name' => $providerUser->getName(),
                'provider' => $provider,
                'provider_id' => $providerUser->getId(),
                'avatar' => $providerUser->getAvatar(),
                'token' => $providerUser->token,
            ]
            );
    }
}

そしてSocialiteコントローラーにDIしてメソッドを委託する形で使うようにした

<?php

namespace App\Http\Controllers;

use App\Services\SocialiteUserService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;

class SocialiteController extends Controller
{
    protected $socialiteUserService;
    public function __construct(SocialiteUserService $socialiteUserService)
    {
        $this->socialiteUserService = $socialiteUserService;
    }

    //認証のリダイレクト処理
    public function redirect($provider)
    {
        return Socialite::driver($provider)->redirect();
    }

    //認証のコールバック処理
    public function callback($provider)
    {
        $user = Socialite::driver($provider)->user();

        //socialiteUserServiceクラスのインスタンスを生成してfindOrCreateUserメソッドを呼び出して登録
        $user = $this->socialiteUserService->findOrCreateUser($user, $provider);

        //ログイン処理
        Auth::login($user, true);

        return redirect('/home');
    }
}

認証できた!
スクリーンショット 2025-02-01 22.55.07.png

最後に

今回はstatefulな認証でできるようにしたが、spaなどの構成のときはstatelessになるので、token認証でoauth認証するようにしたい。
その際の記述としては、
Socialite::driver($provider)->stateless()->redirect()
と加えるだけでできそう。

参考

https://readouble.com/laravel/9.x/ja/socialite.html
https://zenn.dev/takumi_n/articles/laravel-socialite-password

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?