Laravel Sanctum vs Passport 2026: Xác thực API và Câu hỏi Phỏng vấn
Hướng dẫn chi tiết so sánh Laravel Sanctum và Passport cho xác thực API. Bao gồm ví dụ code thực tế và các câu hỏi phỏng vấn thường gặp.

Laravel Sanctum và Passport phục vụ các nhu cầu xác thực API khác nhau. Việc chọn sai package có thể dẫn đến sự phức tạp không cần thiết hoặc lỗ hổng bảo mật. Hướng dẫn này phân tích chi tiết cả hai package với các ví dụ code thực tế và câu hỏi phỏng vấn liên quan.
Sanctum xử lý xác thực SPA và API token đơn giản. Passport triển khai OAuth2 đầy đủ với authorization codes, client credentials và refresh tokens. Hầu hết các ứng dụng chỉ cần Sanctum.
Laravel Sanctum vs Passport: Sự khác biệt Cốt lõi
Sanctum cung cấp xác thực dựa trên token nhẹ, được thiết kế cho các ứng dụng first-party. Package này sử dụng xác thực session dựa trên cookie cho SPA và personal access tokens cho ứng dụng di động và API đơn giản.
Passport triển khai đầy đủ đặc tả OAuth2, bao gồm authorization servers, client credentials grants và xác thực machine-to-machine. Độ phức tạp này cần thiết cho các ứng dụng yêu cầu ủy quyền truy cập của bên thứ ba.
| Tính năng | Sanctum | Passport | |-----------|---------|----------| | Use Case Chính | SPA, Ứng dụng Di động, API Đơn giản | OAuth2 Bên thứ ba, Machine-to-Machine | | Loại Token | Token hash đơn giản | JWT với OAuth2 scopes | | Xác thực Session | Có (dựa trên cookie) | Không | | OAuth2 Grants | Không có | Đặc tả đầy đủ | | Kích thước Package | Tối thiểu | Đáng kể | | Cấu hình | Đơn giản | Phức tạp |
Triển khai Sanctum cho Xác thực SPA
Xác thực SPA của Sanctum dựa vào session cookies Laravel thay vì API tokens. Frontend và backend phải chia sẻ cùng top-level domain để hoạt động.
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, // Token không hết hạn theo mặc định
'middleware' => [
'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
],
];SPA phải gọi endpoint CSRF cookie trước khi thực hiện các request cần xác thực. Bước này thiết lập session và đặt cookie XSRF-TOKEN.
// Frontend: Khởi tạo bảo vệ CSRF trước khi đăng nhập
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();
}Xác thực Token API với Sanctum
Ứng dụng di động và tích hợp bên thứ ba sử dụng personal access tokens thay vì session cookies. Sanctum lưu trữ các token này dưới dạng hash SHA-256 trong database.
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' => ['Thông tin đăng nhập không chính xác.'],
]);
}
// Token với abilities (scopes)
$token = $user->createToken(
$request->device_name,
['read', 'write'] // Abilities tùy chọn
);
return response()->json([
'token' => $token->plainTextToken,
'expires_at' => null // Cấu hình trong sanctum.php
]);
}
public function revokeToken(Request $request)
{
// Thu hồi token hiện tại
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Token đã được thu hồi']);
}
}Bảo vệ các route với middleware auth:sanctum. Sử dụng method tokenCan để kiểm tra abilities của token.
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) {
// Kiểm tra token có ability write không
if (! $request->user()->tokenCan('write')) {
abort(403, 'Token không có quyền write');
}
// Logic tạo post
});
});Sẵn sàng chinh phục phỏng vấn Laravel?
Luyện tập với mô phỏng tương tác, flashcards và bài kiểm tra kỹ thuật.
Khi nào Sử dụng Laravel Passport
Passport trở nên cần thiết khi ứng dụng hoạt động như một authorization server OAuth2. Các kịch bản phổ biến bao gồm:
- Developer bên thứ ba xây dựng tích hợp với API
- Xác thực machine-to-machine giữa các microservices
- Ứng dụng yêu cầu tuân thủ OAuth2 cho khách hàng doanh nghiệp
- Hệ thống cần xoay vòng refresh token và xác thực 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);
}
// Tạo token OAuth2 với 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 cũng hỗ trợ client credentials grant cho xác thực server-to-server mà không cần ngữ cảnh user.
// Xác thực machine-to-machine
// config/auth.php
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
// routes/api.php - Route được bảo vệ bởi client credentials
Route::middleware('client')->group(function () {
Route::get('/machine-data', function () {
return response()->json(['data' => 'Có thể truy cập bởi máy']);
});
});Thực hành Bảo mật Tốt nhất cho Xác thực API Laravel
Cả hai package đều yêu cầu các biện pháp bảo mật bổ sung ngoài cài đặt cơ bản. Hết hạn token, giới hạn tốc độ và xác thực scope đúng cách ngăn chặn các lỗ hổng phổ biến.
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Laravel\Sanctum\Sanctum;
use Laravel\Sanctum\PersonalAccessToken;
class AuthServiceProvider extends ServiceProvider
{
public function boot(): void
{
// Đặt hết hạn token (Sanctum)
Sanctum::authenticateAccessTokensUsing(function ($token, $isValid) {
// Hết hạn token sau 24 giờ
$expiration = config('sanctum.expiration');
if ($expiration === null) {
return $isValid;
}
return $isValid && $token->created_at->gt(now()->subMinutes($expiration));
});
}
}Triển khai rate limiting trên các endpoint xác thực để ngăn chặn tấn công brute force. Laravel 12 cung cấp cấu hình rate limiter linh hoạt thông qua RateLimiting facade.
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());
});
}Câu hỏi Phỏng vấn về Xác thực Laravel
Các buổi phỏng vấn kỹ thuật thường kiểm tra sự hiểu biết về các mẫu xác thực API. Những câu hỏi này xuất hiện trong phỏng vấn developer Laravel ở tất cả các cấp độ.
H: Sự khác biệt giữa xác thực SPA và xác thực token của Sanctum là gì?
Xác thực SPA sử dụng session cookies Laravel với bảo vệ CSRF. Frontend gọi /sanctum/csrf-cookie để thiết lập session, sau đó các request tiếp theo tự động bao gồm session cookie. Xác thực token sử dụng Bearer tokens trong header Authorization, phù hợp cho ứng dụng di động và tích hợp bên thứ ba nơi cookies không thực tế.
H: Khi nào nên chọn Passport thay vì Sanctum?
Passport triển khai OAuth2 đầy đủ, cần thiết khi developer bên thứ ba cần tích hợp với API sử dụng authorization code flow, hoặc khi xác thực machine-to-machine yêu cầu client credentials grants. Sanctum xử lý các ứng dụng first-party đơn giản hơn.
H: Sanctum lưu trữ API tokens như thế nào?
Sanctum lưu trữ hash SHA-256 của mỗi token trong bảng personal_access_tokens. Token văn bản thuần chỉ được trả về một lần khi tạo. Cách tiếp cận này đảm bảo dữ liệu database bị xâm phạm không thể tiết lộ các token hợp lệ.
H: Làm thế nào để triển khai abilities/scopes token trong Sanctum?
// Tạo token với abilities
$token = $user->createToken('api-token', ['posts:read', 'posts:write']);
// Kiểm tra abilities trong controller
if ($request->user()->tokenCan('posts:write')) {
// Được ủy quyền cho thao tác write
}
// Kiểm tra ability dựa trên middleware
Route::middleware(['auth:sanctum', 'ability:posts:write'])
->post('/posts', [PostController::class, 'store']);H: Làm thế nào để thu hồi tất cả token cho một user trong Sanctum?
// Thu hồi tất cả token
$user->tokens()->delete();
// Thu hồi token cụ thể theo ID
$user->tokens()->where('id', $tokenId)->delete();
// Chỉ thu hồi token hiện tại
$request->user()->currentAccessToken()->delete();Di chuyển từ Passport sang Sanctum
Các ứng dụng bắt đầu với Passport nhưng chỉ sử dụng xác thực token đơn giản có thể di chuyển sang Sanctum để giảm độ phức tạp. Việc di chuyển yêu cầu cập nhật tạo token, cấu hình middleware và kiểm tra scope.
// Helper di chuyển: Chuyển đổi token Passport sang Sanctum
use App\Models\User;
use Laravel\Passport\Token;
// Đây là di chuyển một chiều - chạy một lần rồi xóa 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 ?? []
);
}
}
});Cập nhật middleware route từ auth:api sang auth:sanctum và thay thế $request->user()->token()->scopes bằng $request->user()->currentAccessToken()->abilities.
Kết luận
- Sanctum phù hợp với SPA, ứng dụng di động và API first-party với cấu hình tối thiểu
- Passport xử lý authorization server OAuth2 và tích hợp bên thứ ba
- Xác thực SPA sử dụng session cookies; xác thực API sử dụng Bearer tokens
- Token abilities cung cấp kiểm soát quyền chi tiết trong Sanctum
- Rate limiting và hết hạn token là các biện pháp bảo mật thiết yếu bất kể chọn package nào
- Hầu hết các ứng dụng Laravel nên bắt đầu với Sanctum và chỉ thêm Passport khi tuân thủ OAuth2 trở thành yêu cầu
Bắt đầu luyện tập!
Kiểm tra kiến thức với mô phỏng phỏng vấn và bài kiểm tra kỹ thuật.
Chia sẻ
Bài viết liên quan

Laravel Livewire 3 năm 2026: Xây dựng Ứng dụng Reactive và Câu hỏi Phỏng vấn
Hướng dẫn toàn diện về Laravel Livewire 3 để xây dựng ứng dụng reactive bằng PHP thuần. Tìm hiểu về component, validation real-time, tích hợp Alpine.js và chuẩn bị phỏng vấn kỹ thuật.

Laravel Testing 2026: Pest, Mocking va Cau Hoi Phong Van Ky Thuat
Huong dan toan dien ve kiem thu Laravel voi Pest trong nam 2026: unit test, feature test, mocking facade, architecture test, mutation testing va cac cau hoi phong van ky thuat danh cho lap trinh vien PHP.

Laravel 12 năm 2026: Tính năng mới, Starter Kit và Câu hỏi phỏng vấn
Laravel 12 mang đến các starter kit được thiết kế lại với React 19, Vue 3, Livewire 4 và WorkOS AuthKit. Hướng dẫn đầy đủ về tính năng mới, lộ trình nâng cấp và các câu hỏi phỏng vấn trọng tâm cho năm 2026.