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 × React で学ぶ SPA 認証 ― Sanctum 導入備忘録

Posted at

はじめに

Laravel × Reactを使用してSPA開発を行った際に認証機能でLaravel Sanctumをしたのでその備忘録です。少しでもお役に立てば幸いです。内容に誤りがありましたら、ご指摘いただけると大変ありがたいです

Laravel Sanctumとは

LaravelアプリでシンプルにAPI認証やSPA認証を実現するための公式パッケージ。Laravel Sanctumを使用すれば、軽量で柔軟なAPI認証を実装することができます。

(特徴)

APIトークン認証

  • ユーザーごとに複数のAPIトークンを発行可能
  • トークンごとに権限設定可能(例. 投稿用トークン、閲覧用トークンなど)

SPA認証(Cookieベース)

  • 同一ドメイン/サブドメインで安全にログイン状態を保持
  • Vue, React などのSPAと相性が良い

API認証

API認証とは、「APIトークン」を使って認証する方式です。ユーザーがログインするとサーバー側でトークン文字列を発行します。クライアントはそのトークンをHTTPヘッダーにつけてリクエストを行います。

(特徴)

  • Stateless: Cookieやセッションを使わず、トークンのみで認証
  • ドメインが異なっても使用可能
  • トークンごとに権限を付与が可能

(基本構成)

1. インストール

composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

2. モデル設定

ユーザーモデルにHasApiTokenを追加

User.php
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

3. APIトークン利用例

//生成したトークンをフロントに返す
$token = $user->createToken('my-token', ['create', 'update'])->plainTextToken;

// 認証付きAPIルート 
// routes/api.php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

4. クロスオリジンの設定

下記コマンドを実行すると、`cors.php'ファイルがconfigフォルダの中に生成されます。

php artisan config:publish cors
cors.php
'allowed_origins' => ['your-frontend-domain'],

5. ヘッダーで送信

Authorization: Bearer {token}

SPA認証

SPA認証とは、Cookieやセッションを使って認証する方式です。クライアント(Vue, Reactなど)がログインリクエストを行うと、Laravel側でセッションを作成し、Cookieに保存します。そのCookieを使ってクライアントからリクエストがおくられてきたらログイン済みかを判断します。

(特徴)

  • Stateful: Cookieやセッション利用
  • 同一ドメイン or サブドメインのみ使用可能
  • Cookieは自動的に送信される

(基本構成)

1. インストール

composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

2. モデル設定

ユーザーモデルにHasApiTokenを追加

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

3. 認証用コントローラー

// app/Http/Controllers/Auth/SPAAuthController.php
namespace App\Http\Controllers\Auth;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;

class SPAAuthController extends Controller
{
    public function login(Request $request)
    {
        $cred = $request->validate([
            'email' => ['required','email'],
            'password' => ['required'],
        ]);

        if (! Auth::attempt($cred, true)) {
            return response()->json(['message' => 'Invalid credentials'], 422);
        }

        // セッションID再生成(セキュリティ)
        $request->session()->regenerate();

        return response()->json(['message' => 'Logged in']);
    }

    public function me(Request $request)
    {
        return $request->user(); // 認証済みならUser返却
    }

    public function logout(Request $request)
    {
        Auth::guard('web')->logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();
        return response()->json(['message' => 'Logged out']);
    }
}

4. ルーティング

// routes/web.php
use App\Http\Controllers\Auth\SPAAuthController;

Route::post('/login',  [SPAAuthController::class, 'login']);
Route::post('/logout', [SPAAuthController::class, 'logout'])->middleware('auth:web');
Route::middleware('auth:web')->get('/user', function (Request $request) {
    return $request->user();
});

5. .envの設定(例)

SESSION_DOMAIN=.example.com
SANCTUM_STATEFUL_DOMAINS=app.example.com,api.example.com

6. SPA認証のCSRF準備(React)

/sanctum/csrf-cookie を踏んでから /login する必要があります

// axios例
await axios.get('/sanctum/csrf-cookie');
await axios.post('/login', { email, password });

API認証 vs SPA認証

項目 API認証 SPA認証
認証方法 Bearerトークン セッションCookie
状態管理 Stateless Stateful
クロスドメイン OK 不可(同一ドメイン/サブドメインのみ)
主な用途 モバイル・外部API Web SPA

最後に

最後までご覧いただきありがとうございました!

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?