Laravel Sanctum vs Passport 2026: การยืนยันตัวตน API และคำถามสัมภาษณ์
คู่มือฉบับสมบูรณ์เปรียบเทียบ Laravel Sanctum และ Passport สำหรับการยืนยันตัวตน API พร้อมตัวอย่างโค้ดจริงและคำถามสัมภาษณ์ที่พบบ่อย

Laravel Sanctum และ Passport ตอบโจทย์ความต้องการการยืนยันตัวตน API ที่แตกต่างกัน การเลือกแพ็กเกจที่ไม่เหมาะสมอาจนำไปสู่ความซับซ้อนที่ไม่จำเป็นหรือช่องโหว่ด้านความปลอดภัย คู่มือนี้อธิบายทั้งสองแพ็กเกจพร้อมตัวอย่างโค้ดจริงและคำถามสัมภาษณ์ที่เกี่ยวข้อง
Sanctum จัดการการยืนยันตัวตน SPA และ API token แบบง่าย Passport ใช้งาน OAuth2 แบบเต็มรูปแบบพร้อม authorization codes, client credentials และ refresh tokens แอปพลิเคชันส่วนใหญ่ต้องการ Sanctum
Laravel Sanctum vs Passport: ความแตกต่างหลัก
Sanctum ให้การยืนยันตัวตนแบบ token ที่เบา ออกแบบมาสำหรับแอปพลิเคชัน first-party แพ็กเกจนี้ใช้การยืนยันตัวตน session แบบ cookie สำหรับ SPA และ personal access tokens สำหรับแอปมือถือและ API แบบง่าย
Passport ใช้งานข้อกำหนด OAuth2 อย่างครบถ้วน รวมถึง authorization servers, client credentials grants และการยืนยันตัวตน machine-to-machine ความซับซ้อนนี้จำเป็นสำหรับแอปพลิเคชันที่ต้องการอนุญาตการเข้าถึงจากบุคคลที่สาม
| คุณสมบัติ | Sanctum | Passport |
|---|---|---|
| Use Case หลัก | SPA, แอปมือถือ, API แบบง่าย | OAuth2 บุคคลที่สาม, Machine-to-Machine |
| ประเภท Token | Token hash แบบง่าย | JWT พร้อม OAuth2 scopes |
| การยืนยันตัวตน Session | ใช่ (แบบ cookie) | ไม่ |
| OAuth2 Grants | ไม่มี | ข้อกำหนดครบถ้วน |
| ขนาดแพ็กเกจ | เล็ก | ใหญ่ |
| การกำหนดค่า | ง่าย | ซับซ้อน |
การใช้งาน Sanctum สำหรับการยืนยันตัวตน SPA
การยืนยันตัวตน SPA ของ Sanctum พึ่งพา session cookies ของ Laravel แทนที่จะเป็น API tokens Frontend และ backend ต้องแชร์ top-level domain เดียวกันเพื่อให้ทำงานได้
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 ไม่หมดอายุตามค่าเริ่มต้น
'middleware' => [
'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
],
];SPA ต้องเรียก endpoint CSRF cookie ก่อนทำ request ที่ต้องการการยืนยันตัวตน ขั้นตอนนี้สร้าง session และตั้งค่า cookie XSRF-TOKEN
// Frontend: เริ่มต้นการป้องกัน CSRF ก่อนเข้าสู่ระบบ
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();
}การยืนยันตัวตน Token API ด้วย Sanctum
แอปพลิเคชันมือถือและการผสานรวมกับบุคคลที่สามใช้ personal access tokens แทน session cookies Sanctum เก็บ tokens เหล่านี้เป็น hash 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' => ['ข้อมูลประจำตัวที่ให้มาไม่ถูกต้อง'],
]);
}
// Token พร้อม abilities (scopes)
$token = $user->createToken(
$request->device_name,
['read', 'write'] // Abilities ตัวเลือก
);
return response()->json([
'token' => $token->plainTextToken,
'expires_at' => null // กำหนดค่าใน sanctum.php
]);
}
public function revokeToken(Request $request)
{
// เพิกถอน token ปัจจุบัน
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'เพิกถอน Token สำเร็จ']);
}
}ป้องกัน routes ด้วย middleware auth:sanctum ใช้ method tokenCan เพื่อตรวจสอบ abilities ของ 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) {
// ตรวจสอบว่า token มี ability write หรือไม่
if (! $request->user()->tokenCan('write')) {
abort(403, 'Token ไม่มีสิทธิ์ write');
}
// ตรรกะการสร้าง post
});
});พร้อมที่จะพิชิตการสัมภาษณ์ Laravel แล้วหรือยังครับ?
ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ
เมื่อใดควรใช้ Laravel Passport
Passport จำเป็นเมื่อแอปพลิเคชันทำหน้าที่เป็น authorization server OAuth2 สถานการณ์ทั่วไปได้แก่:
- นักพัฒนาบุคคลที่สามสร้างการผสานรวมกับ API
- การยืนยันตัวตน machine-to-machine ระหว่าง microservices
- แอปพลิเคชันที่ต้องการความสอดคล้องกับ OAuth2 สำหรับลูกค้าองค์กร
- ระบบที่ต้องการการหมุนเวียน refresh token และการตรวจสอบ 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);
}
// สร้าง token OAuth2 พร้อม 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 ยังรองรับ client credentials grant สำหรับการยืนยันตัวตน server-to-server โดยไม่ต้องมี context ของ user
// การยืนยันตัวตน machine-to-machine
// config/auth.php
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
// routes/api.php - Route ที่ป้องกันด้วย client credentials
Route::middleware('client')->group(function () {
Route::get('/machine-data', function () {
return response()->json(['data' => 'เข้าถึงได้โดยเครื่อง']);
});
});แนวปฏิบัติด้านความปลอดภัยที่ดีที่สุดสำหรับการยืนยันตัวตน API Laravel
ทั้งสองแพ็กเกจต้องการมาตรการความปลอดภัยเพิ่มเติมนอกเหนือจากการตั้งค่าพื้นฐาน การหมดอายุของ token, การจำกัดอัตรา และการตรวจสอบ scope ที่เหมาะสมป้องกันช่องโหว่ทั่วไป
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Laravel\Sanctum\Sanctum;
use Laravel\Sanctum\PersonalAccessToken;
class AuthServiceProvider extends ServiceProvider
{
public function boot(): void
{
// ตั้งค่าการหมดอายุ token (Sanctum)
Sanctum::authenticateAccessTokensUsing(function ($token, $isValid) {
// Token หมดอายุหลัง 24 ชั่วโมง
$expiration = config('sanctum.expiration');
if ($expiration === null) {
return $isValid;
}
return $isValid && $token->created_at->gt(now()->subMinutes($expiration));
});
}
}ใช้งาน rate limiting บน endpoints การยืนยันตัวตนเพื่อป้องกันการโจมตี brute force Laravel 12 มีการกำหนดค่า rate limiter ที่ยืดหยุ่นผ่าน 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());
});
}คำถามสัมภาษณ์เกี่ยวกับการยืนยันตัวตน Laravel
การสัมภาษณ์ทางเทคนิคมักทดสอบความเข้าใจเกี่ยวกับรูปแบบการยืนยันตัวตน API คำถามเหล่านี้ปรากฏในการสัมภาษณ์นักพัฒนา Laravel ทุกระดับ
ถ: ความแตกต่างระหว่างการยืนยันตัวตน SPA และการยืนยันตัวตน token ของ Sanctum คืออะไร?
การยืนยันตัวตน SPA ใช้ session cookies ของ Laravel พร้อมการป้องกัน CSRF Frontend เรียก /sanctum/csrf-cookie เพื่อสร้าง session จากนั้น requests ถัดไปจะรวม session cookie โดยอัตโนมัติ การยืนยันตัวตน token ใช้ Bearer tokens ใน Authorization header เหมาะสำหรับแอปมือถือและการผสานรวมกับบุคคลที่สามที่ cookies ไม่สะดวก
ถ: เมื่อใดควรเลือก Passport แทน Sanctum?
Passport ใช้งาน OAuth2 แบบเต็ม จำเป็นเมื่อนักพัฒนาบุคคลที่สามต้องการผสานรวมกับ API โดยใช้ authorization code flow หรือเมื่อการยืนยันตัวตน machine-to-machine ต้องการ client credentials grants Sanctum จัดการแอปพลิเคชัน first-party ได้ง่ายกว่า
ถ: Sanctum เก็บ API tokens อย่างไร?
Sanctum เก็บ hash SHA-256 ของแต่ละ token ในตาราง personal_access_tokens Token แบบ plain text จะส่งคืนเพียงครั้งเดียวตอนสร้าง วิธีนี้หมายความว่าข้อมูลฐานข้อมูลที่ถูกบุกรุกไม่สามารถเปิดเผย tokens ที่ใช้งานได้
ถ: จะใช้งาน abilities/scopes ของ token ใน Sanctum อย่างไร?
// สร้าง token พร้อม abilities
$token = $user->createToken('api-token', ['posts:read', 'posts:write']);
// ตรวจสอบ abilities ใน controller
if ($request->user()->tokenCan('posts:write')) {
// ได้รับอนุญาตสำหรับการดำเนินการ write
}
// การตรวจสอบ ability แบบ middleware
Route::middleware(['auth:sanctum', 'ability:posts:write'])
->post('/posts', [PostController::class, 'store']);ถ: จะเพิกถอน tokens ทั้งหมดสำหรับ user ใน Sanctum อย่างไร?
// เพิกถอน tokens ทั้งหมด
$user->tokens()->delete();
// เพิกถอน token เฉพาะตาม ID
$user->tokens()->where('id', $tokenId)->delete();
// เพิกถอนเฉพาะ token ปัจจุบัน
$request->user()->currentAccessToken()->delete();การย้ายจาก Passport ไปยัง Sanctum
แอปพลิเคชันที่เริ่มต้นด้วย Passport แต่ใช้เฉพาะการยืนยันตัวตน token แบบง่ายสามารถย้ายไปยัง Sanctum เพื่อลดความซับซ้อน การย้ายต้องอัปเดตการสร้าง token, การกำหนดค่า middleware และการตรวจสอบ scope
// ตัวช่วยการย้าย: แปลง tokens Passport เป็น Sanctum
use App\Models\User;
use Laravel\Passport\Token;
// นี่คือการย้ายแบบทางเดียว - รันครั้งเดียวแล้วลบ 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 ?? []
);
}
}
});อัปเดต middleware ของ route จาก auth:api เป็น auth:sanctum และแทนที่ $request->user()->token()->scopes ด้วย $request->user()->currentAccessToken()->abilities
บทสรุป
- Sanctum เหมาะกับ SPA, แอปมือถือ และ API first-party ด้วยการกำหนดค่าน้อยที่สุด
- Passport จัดการ authorization server OAuth2 และการผสานรวมกับบุคคลที่สาม
- การยืนยันตัวตน SPA ใช้ session cookies; การยืนยันตัวตน API ใช้ Bearer tokens
- Token abilities ให้การควบคุมสิทธิ์ที่ละเอียดใน Sanctum
- Rate limiting และการหมดอายุ token เป็นมาตรการความปลอดภัยที่จำเป็นไม่ว่าจะเลือกแพ็กเกจใด
- แอปพลิเคชัน Laravel ส่วนใหญ่ควรเริ่มต้นด้วย Sanctum และเพิ่ม Passport เมื่อความสอดคล้องกับ OAuth2 กลายเป็นข้อกำหนด
เริ่มฝึกซ้อมเลย!
ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ
คุณหาบั๊กใน Laravel เจอไหม
โค้ดจริงหนึ่งชิ้น บั๊กที่ซ่อนอยู่หนึ่งจุด วันละหนึ่งครั้ง ลองได้โดยไม่ต้องมีบัญชี

เขียนโดย
Anthony Fillion-Mailletผู้ก่อตั้ง SharpSkill
เป็นนักพัฒนาฟูลสแตกมากว่า 10 ปี ดูแล SharpSkill และรับผิดชอบทุกสิ่งที่เผยแพร่ที่นี่
อัปเดตเมื่อ 26 กรกฎาคม 2569
แชร์
บทความที่เกี่ยวข้อง

คำถามสัมภาษณ์ PHP Laravel Framework 2026: Eloquent, Queues และ Architecture Patterns
คำถามสัมภาษณ์ PHP Laravel framework สำหรับปี 2026 เชี่ยวชาญ Eloquent ORM, สถาปัตยกรรม queue, รูปแบบ service container และความท้าทายด้านการเขียนโค้ดสำหรับตำแหน่ง senior

Laravel Octane ในปี 2026: Swoole, RoadRunner และการเพิ่มประสิทธิภาพ
เรียนรู้ Laravel Octane 2.19 กับ FrankenPHP, Swoole และ RoadRunner ครบถ้วน ตั้งแต่การเลือก server การป้องกัน memory leak การทำงานแบบ concurrent และรูปแบบการ deploy สำหรับ production

คำถามสัมภาษณ์ PHP Laravel Developer 2026: คู่มือเตรียมตัวฉบับสมบูรณ์
คู่มือครอบคลุมสำหรับการเตรียมตัวสัมภาษณ์ PHP Laravel developer ปี 2026 ครอบคลุมคำถามเทคนิคเกี่ยวกับ Eloquent ORM, Service Container, authentication, queue และ testing