目次

Sanctum

概要

Laravel Sanctumでは、主に2つの認証方法が提供されています。それぞれの方法は、異なるユースケースに適しています。

  1. APIトークン認証:

APIトークン認証は、主にサードパーティアプリケーションやモバイルアプリケーションなど、Laravelとは別のドメインや環境で動作するクライアントアプリケーションに適しています。この方法では、ユーザーは一度ログインしてトークンを取得し、その後のリクエストでトークンを使用してAPIにアクセスします。トークンは通常、ヘッダーのAuthorizationフィールドにBearerとして含められます。

  1. SPA認証:

SPA認証は、シングルページアプリケーション(SPA)で使用されることを想定しています。この認証方法は、LaravelとSPAが同じドメインで動作している場合に適しています。SPA認証では、Laravel Sanctumがブラウザのセッションとクッキーを使用して認証を管理します。このため、APIトークン認証とは異なり、トークンを明示的に送信する必要はありません。

これらの違いを踏まえて、以下のようなユースケースにそれぞれの認証方法を適用できます。

どちらの認証方法を選択するかは、アプリケーションの要件や構成によって異なります。

SPA認証

Next.jsを使用している場合、SPA認証とAPIトークン認証のどちらを選択するかは、アプリケーションの要件と構成によって異なります。

  1. 同じドメイン上で動作する場合: LaravelとNext.jsが同じドメイン上で動作している場合、SPA認証を使用することが一般的です。これにより、ブラウザのセッションとクッキーを活用して認証を管理できます。
  2. 異なるドメイン上で動作する場合: LaravelとNext.jsが異なるドメイン上で動作している場合、APIトークン認証を使用することが推奨されます。この方法では、クライアントアプリケーションがトークンを使用してAPIにアクセスし、CORSポリシーも適切に設定する必要があります。

Next.jsを使用している場合でも、アプリケーションの構成や要件によって適切な認証方法を選択することが重要です。

SPA認証を採用するメリットもいくつかあります。

  1. シームレスな認証: SPA認証は、同一ドメイン内での通信において、Cookieを使用して認証情報を管理するため、APIとフロントエンド間のやりとりがシームレスになります。これにより、開発者は認証に関する処理を簡単に実装できます。
  2. セッション管理の簡素化: SPA認証では、バックエンドサーバーがセッション情報を管理します。これにより、クライアント側でトークンの有効期限やリフレッシュの管理をする必要がなくなります。
  3. セキュリティ: 同一ドメイン上での通信においては、Cookieが自動的に送信されるため、トークンを明示的に付与する必要がありません。このため、トークンの取り扱いに関するセキュリティリスクが低減されます。

ただし、SPA認証を使用する場合は、以下のような制約があります。

SPA認証とAPIトークン認証のどちらを採用するかは、アプリケーションの要件やセキュリティ要件に応じて検討することが重要です。

APIトークン認証

同じドメイン上で動作している場合でも、APIトークン認証を採用するメリットがいくつかあります。

  1. ステートレス性: APIトークン認証はステートレスであるため、サーバー側でセッション情報を保持する必要がなく、スケーラビリティが向上します。これにより、分散システムやマイクロサービスアーキテクチャに適しています。
  2. クライアント側の制御: APIトークン認証では、クライアントがトークンを持っている限り認証が持続します。これにより、クライアント側でトークンの有効期限やリフレッシュを管理することができ、必要に応じてアクセス制御を行うことができます。
  3. 複数のクライアントに対応: APIトークン認証を使用すると、同じバックエンドAPIに対して複数のクライアントアプリケーションやデバイスがアクセスできるようになります。これにより、Webアプリケーションだけでなく、モバイルアプリや他のサービスとの連携も容易になります。

ただし、APIトークン認証を使用する場合、トークンの取り扱いに注意が必要です。トークンが漏洩すると、悪意のある第三者がAPIにアクセスできるようになってしまうため、セキュリティ対策を適切に行う必要があります。

SPA認証実装例

実装の簡単さは、開発者の経験やプロジェクトの要件によって異なりますが、一般的にはSPA認証の方が実装が簡単です。なぜなら、セッション管理がバックエンド側で行われるため、クライアント側での認証トークンの管理が不要になるからです。

以下に、LaravelとNext.jsを使用したSPA認証の例を示します。

  1. Laravel側で、config/sanctum.phpファイルでstatefulの設定を行います。
'stateful' => explode(',', env(
    'SANCTUM_STATEFUL_DOMAINS',
    'localhost,127.0.0.1'
)),
  1. routes/api.phpに、認証ルートを設定します。
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
 
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});
 
Route::post('/login', 'AuthController@login');
  1. AuthControllerを作成し、ログイン処理を実装します。
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
 
public function login(Request $request)
{
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
    ]);
 
    if (!Auth::attempt($request->only('email', 'password'))) {
        throw ValidationException::withMessages([
            'email' => ['認証に失敗しました。'],
        ]);
    }
 
    $request->session()->regenerate();
 
    return response()->json(['message' => 'ログインに成功しました。']);
}
  1. Next.js側で、ログインページを作成します。
import { useState } from 'react';
import axios from 'axios';
 
const Login = () => {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
 
    const handleSubmit = async (e) => {
        e.preventDefault();
 
        try {
            await axios.post('/api/login', {
                email,
                password,
            }, { withCredentials: true });
 
            // ログイン後の処理
        } catch (error) {
            console.error(error);
        }
    };
 
    return (
        <div>
            <form onSubmit={handleSubmit}>
                <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
                <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
                <button type="submit">ログイン</button>
            </form>
        </div>
    );
};
 
export default Login;

この例では、Next.jsのログインページでメールアドレスとパスワードを入力し、LaravelのAPIにリクエストを送信しています。認証に成功すると、Laravel側でセッションが管理され、auth:sanctumミドルウェアで保護されたルートにアクセスできるようになります。