Laravel Sanctum vs Passport 2026: API 인증 비교와 면접 질문 완벽 가이드
Laravel Sanctum과 Passport의 차이점을 실무 코드 예제와 함께 상세히 분석합니다. SPA 인증, API 토큰, OAuth2 구현 방법과 기술 면접에서 자주 출제되는 질문 및 모범 답변을 제공합니다.

Laravel Sanctum과 Passport는 서로 다른 API 인증 요구사항을 처리하며, 잘못된 선택은 불필요한 복잡성이나 보안 취약점으로 이어질 수 있습니다. 본 가이드에서는 실무 코드 예제와 실제 면접 질문을 통해 두 패키지의 차이점을 상세히 분석합니다.
Sanctum은 SPA 인증과 간단한 API 토큰을 처리합니다. Passport는 인가 코드, 클라이언트 자격 증명, 리프레시 토큰을 포함한 완전한 OAuth2를 구현합니다. 대부분의 애플리케이션에는 Sanctum이 적합합니다.
Laravel Sanctum vs Passport: 핵심 차이점
Sanctum은 퍼스트파티 애플리케이션을 위해 설계된 경량 토큰 기반 인증을 제공합니다. SPA에는 쿠키 기반 세션 인증을, 모바일 앱과 간단한 API에는 개인 액세스 토큰을 사용합니다.
Passport는 인가 서버, 클라이언트 자격 증명 그랜트, 머신 투 머신 인증을 포함한 완전한 OAuth2 사양을 구현합니다. 이러한 복잡성은 서드파티 액세스 인가가 필요한 애플리케이션에 적합합니다.
| 기능 | Sanctum | Passport | |---------|---------|----------| | 주요 사용 사례 | SPA, 모바일 앱, 단순 API | 서드파티 OAuth2, 머신 투 머신 | | 토큰 타입 | 단순 해시 토큰 | OAuth2 스코프가 있는 JWT | | 세션 인증 | 지원 (쿠키 기반) | 미지원 | | OAuth2 그랜트 | 없음 | 전체 사양 지원 | | 패키지 크기 | 최소 | 대용량 | | 설정 | 간단 | 복잡 |
Sanctum을 이용한 SPA 인증 구현
Sanctum SPA 인증은 API 토큰이 아닌 Laravel 세션 쿠키에 의존합니다. 프론트엔드와 백엔드는 동일한 최상위 도메인을 공유해야 합니다.
return [
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),
'expiration' => null, // Tokens never expire by default
'middleware' => [
'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
],
];SPA는 인증된 요청을 보내기 전에 CSRF 쿠키 엔드포인트를 호출해야 합니다. 이를 통해 세션이 설정되고 XSRF-TOKEN 쿠키가 생성됩니다.
// Frontend: Initialize CSRF protection before login
async function initializeAuth() {
await fetch('/sanctum/csrf-cookie', {
credentials: 'include'
});
}
async function login(email, password) {
await initializeAuth();
const response = await fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-XSRF-TOKEN': getCookie('XSRF-TOKEN'),
'Accept': 'application/json'
},
credentials: 'include',
body: JSON.stringify({ email, password })
});
return response.json();
}Sanctum API 토큰 인증
모바일 애플리케이션과 서드파티 통합에서는 세션 쿠키 대신 개인 액세스 토큰을 사용합니다. Sanctum은 이러한 토큰을 SHA-256 해시로 데이터베이스에 저장합니다.
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
class AuthController extends Controller
{
public function createToken(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
'device_name' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
// Token with abilities (scopes)
$token = $user->createToken(
$request->device_name,
['read', 'write'] // Optional abilities
);
return response()->json([
'token' => $token->plainTextToken,
'expires_at' => null // Configure in sanctum.php
]);
}
public function revokeToken(Request $request)
{
// Revoke current token
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Token revoked']);
}
}auth:sanctum 미들웨어로 라우트를 보호합니다. 토큰 권한은 tokenCan 메서드로 확인할 수 있습니다.
use Illuminate\Support\Facades\Route;
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', function (Request $request) {
return $request->user();
});
Route::post('/posts', function (Request $request) {
// Check if token has write ability
if (! $request->user()->tokenCan('write')) {
abort(403, 'Token does not have write permissions');
}
// Create post logic
});
});Laravel 면접 준비가 되셨나요?
인터랙티브 시뮬레이터, flashcards, 기술 테스트로 연습하세요.
Laravel Passport 사용 시점
Passport는 애플리케이션이 OAuth2 인가 서버로 작동해야 할 때 필요합니다. 일반적인 시나리오는 다음과 같습니다.
- 서드파티 개발자가 API와 통합을 구축하는 경우
- 마이크로서비스 간 머신 투 머신 인증
- 엔터프라이즈 고객을 위한 OAuth2 규정 준수가 필요한 경우
- 리프레시 토큰 순환과 JWT 검증이 필요한 시스템
namespace App\Http\Controllers\Api;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class PassportController extends Controller
{
public function issueToken(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
return response()->json([
'error' => 'invalid_credentials'
], 401);
}
// Create OAuth2 token with scopes
$token = $user->createToken('API Token', ['read-posts', 'write-posts']);
return response()->json([
'access_token' => $token->accessToken,
'token_type' => 'Bearer',
'expires_at' => $token->token->expires_at
]);
}
}Passport는 사용자 컨텍스트 없이 서버 간 인증을 위한 클라이언트 자격 증명 그랜트도 지원합니다.
// Machine-to-machine authentication
// config/auth.php
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
// routes/api.php - Client credentials protected route
Route::middleware('client')->group(function () {
Route::get('/machine-data', function () {
return response()->json(['data' => 'Machine accessible']);
});
});Laravel API 인증 보안 모범 사례
두 패키지 모두 기본 설정 이상의 추가 보안 조치가 필요합니다. 토큰 만료, 속도 제한, 적절한 스코프 검증을 통해 일반적인 취약점을 방지할 수 있습니다.
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Laravel\Sanctum\Sanctum;
use Laravel\Sanctum\PersonalAccessToken;
class AuthServiceProvider extends ServiceProvider
{
public function boot(): void
{
// Set token expiration (Sanctum)
Sanctum::authenticateAccessTokensUsing(function ($token, $isValid) {
// Expire tokens after 24 hours
$expiration = config('sanctum.expiration');
if ($expiration === null) {
return $isValid;
}
return $isValid && $token->created_at->gt(now()->subMinutes($expiration));
});
}
}브루트포스 공격을 방지하기 위해 인증 엔드포인트에 속도 제한을 구현합니다. Laravel 12는 RateLimiting 파사드를 통해 유연한 속도 제한 설정을 제공합니다.
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiting;
public function boot(): void
{
RateLimiting::for('login', function ($request) {
return Limit::perMinute(5)->by($request->ip());
});
RateLimiting::for('api', function ($request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
}Laravel 인증 면접 질문
기술 면접에서는 API 인증 패턴에 대한 이해가 자주 테스트됩니다. 다음 질문들은 모든 수준의 Laravel 개발자 면접에서 출제됩니다.
Q: Sanctum의 SPA 인증과 토큰 인증의 차이점은 무엇입니까?
SPA 인증은 CSRF 보호가 포함된 Laravel 세션 쿠키를 사용합니다. 프론트엔드가 /sanctum/csrf-cookie를 호출하여 세션을 설정하면, 이후 요청에는 세션 쿠키가 자동으로 포함됩니다. 토큰 인증은 Authorization 헤더에 Bearer 토큰을 사용하며, 쿠키가 실용적이지 않은 모바일 앱과 서드파티 통합에 적합합니다.
Q: Sanctum 대신 Passport를 선택해야 하는 경우는 언제입니까?
Passport는 완전한 OAuth2를 구현하며, 서드파티 개발자가 인가 코드 플로우를 사용하여 API와 통합해야 하거나 머신 투 머신 인증에 클라이언트 자격 증명 그랜트가 필요한 경우 필요합니다. Sanctum은 퍼스트파티 애플리케이션을 더 간단하게 처리합니다.
Q: Sanctum은 API 토큰을 어떻게 저장합니까?
Sanctum은 각 토큰의 SHA-256 해시를 personal_access_tokens 테이블에 저장합니다. 평문 토큰은 생성 시 한 번만 반환됩니다. 이 접근 방식은 데이터베이스가 유출되더라도 유효한 토큰이 노출되지 않음을 의미합니다.
Q: Sanctum에서 토큰 abilities(스코프)를 구현하는 방법은?
// Creating token with abilities
$token = $user->createToken('api-token', ['posts:read', 'posts:write']);
// Checking abilities in controller
if ($request->user()->tokenCan('posts:write')) {
// Authorized for write operations
}
// Middleware-based ability check
Route::middleware(['auth:sanctum', 'ability:posts:write'])
->post('/posts', [PostController::class, 'store']);Q: Sanctum에서 사용자의 모든 토큰을 해지하는 방법은?
// Revoke all tokens
$user->tokens()->delete();
// Revoke specific token by ID
$user->tokens()->where('id', $tokenId)->delete();
// Revoke current token only
$request->user()->currentAccessToken()->delete();Passport에서 Sanctum으로 마이그레이션
Passport로 시작했지만 단순 토큰 인증만 사용하는 애플리케이션은 복잡성을 줄이기 위해 Sanctum으로 마이그레이션할 수 있습니다. 마이그레이션에는 토큰 생성, 미들웨어 구성, 스코프 검사 업데이트가 필요합니다.
// Migration helper: Convert Passport tokens to Sanctum
use App\Models\User;
use Laravel\Passport\Token;
// This is a one-way migration - run once then remove Passport
User::chunk(100, function ($users) {
foreach ($users as $user) {
$passportTokens = Token::where('user_id', $user->id)
->where('revoked', false)
->get();
foreach ($passportTokens as $token) {
$user->createToken(
$token->name ?? 'migrated-token',
$token->scopes ?? []
);
}
}
});라우트 미들웨어를 auth:api에서 auth:sanctum으로 업데이트하고, $request->user()->token()->scopes를 $request->user()->currentAccessToken()->abilities로 교체합니다.
결론
- Sanctum은 최소한의 구성으로 SPA, 모바일 앱, 퍼스트파티 API에 적합합니다
- Passport는 OAuth2 인가 서버와 서드파티 통합을 처리합니다
- SPA 인증은 세션 쿠키를 사용하고, API 인증은 Bearer 토큰을 사용합니다
- 토큰 abilities는 Sanctum에서 세밀한 권한 제어를 제공합니다
- 속도 제한과 토큰 만료는 패키지 선택에 관계없이 필수적인 보안 조치입니다
- 대부분의 Laravel 애플리케이션은 Sanctum으로 시작하고, OAuth2 규정 준수가 요구될 때만 Passport를 추가해야 합니다
연습을 시작하세요!
면접 시뮬레이터와 기술 테스트로 지식을 테스트하세요.
태그
공유
관련 기사

Laravel 12 새로운 기능 총정리: 스타터 킷, WorkOS AuthKit, 업그레이드 가이드 및 면접 질문 (2026)
Laravel 12의 새로운 기능을 상세히 분석합니다. 스타터 킷 개편, WorkOS AuthKit 통합, Carbon 3 필수화, 업그레이드 가이드, 그리고 2026년 Laravel 면접 질문까지 실무에 필요한 모든 내용을 다룹니다.

Laravel 큐와 잡: 비동기 아키텍처와 면접 대비 2026
Laravel 큐 시스템의 내부 동작, 잡 배치 처리, 체이닝, 재시도 전략을 상세히 분석합니다. 2026년 기술 면접에서 출제되는 큐 아키텍처 핵심 개념을 체계적으로 정리합니다.

Laravel Middleware 완벽 가이드: 인증, 속도 제한, 커스텀 미들웨어 구축
Laravel 미들웨어의 파이프라인 구조부터 인증, 속도 제한(Rate Limiting), 커스텀 미들웨어 작성, 프로덕션 패턴까지 실무 코드 예제와 함께 체계적으로 정리합니다.