Cara Membuat REST API Laravel Menggunakan Sanctum dari Awal
Apa Itu REST API Laravel?
REST API adalah antarmuka yang memungkinkan aplikasi saling bertukar data melalui protokol HTTP.
Sebagai contoh, aplikasi mobile dapat mengambil data produk dari server Laravel melalui endpoint:
GET /api/products
Untuk menambahkan produk, aplikasi dapat mengirim request:
POST /api/products
REST API biasanya menggunakan beberapa metode HTTP berikut:
| Metode | Fungsi |
|---|---|
GET | Mengambil data |
POST | Menambahkan data |
PUT atau PATCH | Memperbarui data |
DELETE | Menghapus data |
Data umumnya dikirim dan diterima menggunakan format JSON.
Contoh respons JSON:
{
"success": true,
"message": "Data produk berhasil ditemukan",
"data": {
"id": 1,
"name": "Laptop",
"price": 7500000
}
}
Apa Itu Laravel Sanctum?
Laravel Sanctum adalah sistem autentikasi ringan untuk aplikasi yang membutuhkan API token, aplikasi mobile, atau autentikasi SPA.
Untuk autentikasi berbasis token, Sanctum akan menyimpan token pengguna dalam tabel database. Token kemudian dikirim melalui header Authorization dengan format Bearer Token. (Laravel)
Contoh header request:
Authorization: Bearer TOKEN_PENGGUNA
Accept: application/json
Sanctum cocok digunakan untuk:
REST API sederhana.
Aplikasi Android atau iOS.
Integrasi aplikasi pihak ketiga.
Dashboard berbasis React atau Vue.
Sistem yang membutuhkan personal access token.
API internal perusahaan.
Untuk sistem OAuth yang kompleks dengan authorization server, Laravel Passport mungkin lebih sesuai. Namun, untuk mayoritas REST API berbasis token, Sanctum lebih sederhana untuk diterapkan.
Hasil API yang Akan Dibuat
Pada tutorial ini, kita akan membuat beberapa endpoint berikut:
| Metode | Endpoint | Fungsi | Akses |
|---|---|---|---|
POST | /api/register | Membuat akun | Publik |
POST | /api/login | Login dan membuat token | Publik |
GET | /api/user | Mengambil pengguna aktif | Token |
POST | /api/logout | Menghapus token aktif | Token |
GET | /api/products | Menampilkan produk | Token |
POST | /api/products | Menambahkan produk | Token |
GET | /api/products/{id} | Detail produk | Token |
PUT | /api/products/{id} | Memperbarui produk | Token |
DELETE | /api/products/{id} | Menghapus produk | Token |
Persiapan Project
Pastikan komputer atau server telah memiliki:
PHP sesuai kebutuhan versi Laravel.
Composer.
MySQL atau MariaDB.
Extension PHP yang dibutuhkan Laravel.
Postman, Insomnia, atau aplikasi pengujian API lainnya.
Periksa versi PHP:
php -v
Periksa Composer:
composer --version
Langkah 1: Membuat Project Laravel
Buat project Laravel baru:
composer create-project laravel/laravel laravel-api
Masuk ke folder project:
cd laravel-api
Jalankan development server:
php artisan serve
Secara default, aplikasi dapat diakses melalui:
http://127.0.0.1:8000
Langkah 2: Mengatur Database
Buat database baru, misalnya:
laravel_api
Kemudian buka file .env dan sesuaikan konfigurasi database:
APP_NAME="Laravel API"
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://127.0.0.1:8000
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_api
DB_USERNAME=root
DB_PASSWORD=
Jika APP_KEY masih kosong, jalankan:
php artisan key:generate
Setelah mengubah .env, bersihkan cache konfigurasi:
php artisan optimize:clear
Langkah 3: Menginstal Laravel Sanctum
Pada Laravel modern, jalankan:
php artisan install:api
Perintah tersebut akan memasang Laravel Sanctum dan membuat file:
routes/api.php
Route di dalam routes/api.php secara otomatis menggunakan middleware grup api dan memperoleh prefix /api. Karena itu, route /products di dalam file tersebut akan diakses melalui /api/products. (Laravel)
Jika menggunakan versi Laravel lama dan perintah install:api tidak tersedia, Sanctum dapat dipasang menggunakan:
composer require laravel/sanctum
Kemudian publish konfigurasi jika dibutuhkan:
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Langkah 4: Menjalankan Migration
Jalankan migration:
php artisan migrate
Sanctum membutuhkan tabel:
personal_access_tokens
Tabel tersebut digunakan untuk menyimpan token API pengguna.
Periksa database dan pastikan beberapa tabel berikut sudah tersedia:
users
personal_access_tokens
migrations
Langkah 5: Memeriksa Model User
Buka file:
app/Models/User.php
Pastikan model User menggunakan trait HasApiTokens:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
Trait HasApiTokens menyediakan fungsi untuk membuat, membaca, dan menghapus token milik pengguna. Token disimpan dalam bentuk hash pada database, sedangkan nilai token asli hanya diperoleh ketika token pertama kali dibuat. (Laravel)
Langkah 6: Membuat AuthController
Buat controller autentikasi:
php artisan make:controller Api/AuthController
Buka file:
app/Http/Controllers/Api/AuthController.php
Isi dengan kode berikut:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
class AuthController extends Controller
{
public function register(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => [
'required',
'email',
'max:255',
'unique:users,email',
],
'password' => [
'required',
'string',
'min:8',
'confirmed',
],
'device_name' => [
'nullable',
'string',
'max:100',
],
]);
$user = User::create([
'name' => $validated['name'],
'email' => $validated['email'],
'password' => $validated['password'],
]);
$token = $user->createToken(
$validated['device_name'] ?? 'api-token'
)->plainTextToken;
return response()->json([
'success' => true,
'message' => 'Registrasi berhasil.',
'data' => [
'user' => $user,
'token' => $token,
'token_type' => 'Bearer',
],
], 201);
}
public function login(Request $request): JsonResponse
{
$validated = $request->validate([
'email' => ['required', 'email'],
'password' => ['required', 'string'],
'device_name' => [
'nullable',
'string',
'max:100',
],
]);
$user = User::where('email', $validated['email'])->first();
if (! $user || ! Hash::check(
$validated['password'],
$user->password
)) {
throw ValidationException::withMessages([
'email' => [
'Email atau password yang dimasukkan tidak sesuai.',
],
]);
}
$token = $user->createToken(
$validated['device_name'] ?? 'api-token'
)->plainTextToken;
return response()->json([
'success' => true,
'message' => 'Login berhasil.',
'data' => [
'user' => $user,
'token' => $token,
'token_type' => 'Bearer',
],
]);
}
public function user(Request $request): JsonResponse
{
return response()->json([
'success' => true,
'message' => 'Data pengguna berhasil ditemukan.',
'data' => $request->user(),
]);
}
public function logout(Request $request): JsonResponse
{
$request->user()
->currentAccessToken()
?->delete();
return response()->json([
'success' => true,
'message' => 'Logout berhasil.',
]);
}
public function logoutAll(Request $request): JsonResponse
{
$request->user()->tokens()->delete();
return response()->json([
'success' => true,
'message' => 'Semua token berhasil dihapus.',
]);
}
}
Proses login memeriksa password menggunakan Hash::check, kemudian membuat token melalui createToken().
Token harus segera dikirim kepada pengguna setelah dibuat karena nilai token asli tidak dapat dibaca kembali dari database. Sanctum hanya menyimpan versi hash token tersebut. (Laravel)
Langkah 7: Membuat Route Autentikasi
Buka:
routes/api.php
Isi route autentikasi:
<?php
use App\Http\Controllers\Api\AuthController;
use Illuminate\Support\Facades\Route;
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', [AuthController::class, 'user']);
Route::post('/logout', [AuthController::class, 'logout']);
Route::post('/logout-all', [AuthController::class, 'logoutAll']);
});
Middleware:
auth:sanctum
memastikan endpoint hanya dapat diakses menggunakan pengguna yang sudah terautentikasi atau memiliki Bearer Token yang valid. (Laravel)
Langkah 8: Membuat Model dan Migration Produk
Buat model sekaligus migration:
php artisan make:model Product -m
Buka file migration yang baru dibuat pada:
database/migrations
Isi method up():
public function up(): void
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description')->nullable();
$table->unsignedBigInteger('price');
$table->unsignedInteger('stock')->default(0);
$table->timestamps();
});
}
Kemudian jalankan:
php artisan migrate
Langkah 9: Mengatur Model Product
Buka:
app/Models/Product.php
Isi model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
protected $fillable = [
'name',
'description',
'price',
'stock',
];
protected function casts(): array
{
return [
'price' => 'integer',
'stock' => 'integer',
];
}
}
Properti $fillable menentukan field yang dapat diisi melalui mass assignment.
Langkah 10: Membuat ProductController
Jalankan:
php artisan make:controller Api/ProductController --api
Buka:
app/Http/Controllers/Api/ProductController.php
Isi dengan kode berikut:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Product;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function index(): JsonResponse
{
$products = Product::query()
->latest()
->paginate(10);
return response()->json([
'success' => true,
'message' => 'Data produk berhasil ditemukan.',
'data' => $products,
]);
}
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => [
'required',
'string',
'max:255',
],
'description' => [
'nullable',
'string',
],
'price' => [
'required',
'integer',
'min:0',
],
'stock' => [
'required',
'integer',
'min:0',
],
]);
$product = Product::create($validated);
return response()->json([
'success' => true,
'message' => 'Produk berhasil ditambahkan.',
'data' => $product,
], 201);
}
public function show(Product $product): JsonResponse
{
return response()->json([
'success' => true,
'message' => 'Detail produk berhasil ditemukan.',
'data' => $product,
]);
}
public function update(
Request $request,
Product $product
): JsonResponse {
$validated = $request->validate([
'name' => [
'sometimes',
'required',
'string',
'max:255',
],
'description' => [
'sometimes',
'nullable',
'string',
],
'price' => [
'sometimes',
'required',
'integer',
'min:0',
],
'stock' => [
'sometimes',
'required',
'integer',
'min:0',
],
]);
$product->update($validated);
return response()->json([
'success' => true,
'message' => 'Produk berhasil diperbarui.',
'data' => $product->fresh(),
]);
}
public function destroy(Product $product): JsonResponse
{
$product->delete();
return response()->json([
'success' => true,
'message' => 'Produk berhasil dihapus.',
]);
}
}
Controller tersebut menangani proses:
Menampilkan daftar produk.
Menambahkan produk.
Menampilkan detail produk.
Memperbarui produk.
Menghapus produk.
Laravel akan menggunakan route model binding untuk mencari produk berdasarkan ID. Jika produk tidak ditemukan, Laravel mengembalikan respons 404 secara otomatis.
Langkah 11: Membuat Route CRUD Produk
Tambahkan ProductController pada routes/api.php:
<?php
use App\Http\Controllers\Api\AuthController;
use App\Http\Controllers\Api\ProductController;
use Illuminate\Support\Facades\Route;
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', [AuthController::class, 'user']);
Route::post('/logout', [AuthController::class, 'logout']);
Route::post('/logout-all', [AuthController::class, 'logoutAll']);
Route::apiResource('products', ProductController::class);
});
Route::apiResource() akan membuat route REST API secara otomatis untuk method:
index
store
show
update
destroy
Periksa seluruh route dengan:
php artisan route:list --path=api
Langkah 12: Menguji Register
Gunakan Postman atau aplikasi pengujian API.
Endpoint
POST http://127.0.0.1:8000/api/register
Header
Accept: application/json
Content-Type: application/json
Body JSON
{
"name": "Gugun Nurdiansyah",
"email": "gugun@example.com",
"password": "password123",
"password_confirmation": "password123",
"device_name": "Postman"
}
Jika berhasil, API akan menghasilkan respons:
{
"success": true,
"message": "Registrasi berhasil.",
"data": {
"user": {
"name": "Gugun Nurdiansyah",
"email": "gugun@example.com"
},
"token": "1|contoh-token-sanctum",
"token_type": "Bearer"
}
}
Simpan token tersebut untuk mengakses endpoint yang dilindungi.
Langkah 13: Menguji Login
Endpoint
POST http://127.0.0.1:8000/api/login
Body JSON
{
"email": "gugun@example.com",
"password": "password123",
"device_name": "Postman"
}
Salin nilai token dari respons login.
Langkah 14: Menguji Endpoint yang Dilindungi
Buka endpoint:
GET http://127.0.0.1:8000/api/user
Tambahkan header:
Accept: application/json
Authorization: Bearer TOKEN_ANDA
Pada Postman, token juga dapat dimasukkan melalui:
Authorization → Bearer Token
Sanctum membaca API token dari header Authorization dengan format Bearer Token. (Laravel)
Jika token tidak diberikan atau tidak valid, API akan menghasilkan respons:
{
"message": "Unauthenticated."
}
Langkah 15: Menambahkan Produk
Endpoint
POST http://127.0.0.1:8000/api/products
Header
Accept: application/json
Content-Type: application/json
Authorization: Bearer TOKEN_ANDA
Body JSON
{
"name": "Aplikasi Point of Sales",
"description": "Aplikasi kasir dan inventory berbasis web.",
"price": 300000,
"stock": 100
}
Langkah 16: Menampilkan Daftar Produk
Gunakan:
GET http://127.0.0.1:8000/api/products
Sertakan Bearer Token pada header request.
Langkah 17: Memperbarui Produk
Gunakan endpoint:
PUT http://127.0.0.1:8000/api/products/1
Body JSON:
{
"name": "OVLA Point of Sales",
"price": 350000,
"stock": 150
}
Anda juga dapat menggunakan metode:
PATCH
untuk memperbarui sebagian data.
Langkah 18: Menghapus Produk
Gunakan:
DELETE http://127.0.0.1:8000/api/products/1
Tambahkan Bearer Token pada header.
Langkah 19: Logout dan Menghapus Token
Gunakan endpoint:
POST http://127.0.0.1:8000/api/logout
Logout akan menghapus token yang sedang digunakan:
$request->user()
->currentAccessToken()
?->delete();
Sanctum juga memungkinkan aplikasi menghapus seluruh token pengguna atau hanya token tertentu melalui relasi tokens. (Laravel)
Setelah logout, token lama tidak dapat digunakan kembali.
Menambahkan Masa Berlaku Token
Secara default, token Sanctum tidak kedaluwarsa sampai token tersebut dihapus atau dicabut. Sanctum menyediakan konfigurasi expiration global maupun waktu kedaluwarsa untuk setiap token. (Laravel)
Contoh token berlaku selama 30 hari:
$token = $user->createToken(
'api-token',
['*'],
now()->addDays(30)
)->plainTextToken;
Untuk mengatur masa berlaku global, periksa:
config/sanctum.php
Contohnya:
'expiration' => 43200,
Nilai tersebut menggunakan satuan menit.
Token yang sudah kedaluwarsa dapat dibersihkan menggunakan:
php artisan sanctum:prune-expired --hours=24
Perintah tersebut dapat dijadwalkan menggunakan Laravel Scheduler.
Menggunakan Token Abilities
Sanctum memungkinkan token diberikan kemampuan atau abilities tertentu. Fitur ini serupa dengan scope dan dapat digunakan untuk membatasi tindakan token. (Laravel)
Contoh membuat token dengan kemampuan membaca dan menulis produk:
$token = $user->createToken(
'api-token',
[
'products:read',
'products:write',
]
)->plainTextToken;
Kemampuan token dapat diperiksa melalui:
if ($request->user()->tokenCan('products:write')) {
// Pengguna diizinkan mengubah produk.
}
Pembatasan abilities berguna ketika aplikasi memiliki beberapa jenis integrasi atau perangkat.
Error yang Sering Terjadi
Route api.php Tidak Ditemukan
Pada Laravel modern, jalankan:
php artisan install:api
Perintah tersebut membuat routes/api.php dan memasang Sanctum. (Laravel)
Error Table personal_access_tokens Tidak Ditemukan
Jalankan:
php artisan migrate
Pastikan koneksi database pada .env sudah benar.
Error Call to Undefined Method createToken
Pastikan model User menggunakan:
use Laravel\Sanctum\HasApiTokens;
dan:
use HasApiTokens;
API Selalu Menghasilkan Unauthenticated
Periksa apakah request sudah menyertakan:
Authorization: Bearer TOKEN_ANDA
Accept: application/json
Jangan menambahkan tanda kutip pada token.
Validasi Mengarahkan ke Halaman Login
Pastikan header berikut tersedia:
Accept: application/json
Header tersebut membantu Laravel mengenali bahwa request mengharapkan respons JSON.
Route Menghasilkan 404
Periksa route:
php artisan route:list --path=api
Kemudian bersihkan cache:
php artisan optimize:clear
Pastikan URL menggunakan prefix:
/api
Data Tidak Dapat Disimpan
Periksa properti $fillable pada model serta konfigurasi database.
Token Tidak Dapat Digunakan Setelah Login
Pastikan token yang digunakan adalah nilai:
$token->plainTextToken
bukan data token yang tersimpan pada database.
Keamanan REST API Laravel
Gunakan HTTPS
Pada server production, API harus menggunakan HTTPS agar token dan data request tidak dikirim melalui koneksi yang tidak terenkripsi.
Jangan Simpan Token di Log
Hindari mencatat Bearer Token, password, API key, atau kredensial pengguna ke dalam file log.
Gunakan Validasi
Setiap data yang masuk harus divalidasi sebelum disimpan atau diproses.
Batasi Masa Berlaku Token
Untuk aplikasi dengan risiko tinggi, gunakan masa berlaku token dan mekanisme pembaruan yang terkontrol.
Gunakan Token Abilities
Berikan kemampuan sesuai kebutuhan setiap aplikasi atau perangkat.
Terapkan Rate Limiting
Rate limiting membantu membatasi jumlah request dalam periode tertentu untuk mengurangi penyalahgunaan API.
Hapus Token Saat Logout
Token yang sudah tidak digunakan harus dicabut atau dihapus.
Jangan Mengirim Detail Error di Production
Gunakan konfigurasi:
APP_ENV=production
APP_DEBUG=false
Lindungi File .env
File .env tidak boleh dapat diakses melalui internet atau disimpan dalam repository publik.
Struktur Project yang Dihasilkan
Setelah tutorial selesai, beberapa file penting yang digunakan adalah:
app/
├── Http/
│ └── Controllers/
│ └── Api/
│ ├── AuthController.php
│ └── ProductController.php
├── Models/
│ ├── Product.php
│ └── User.php
database/
└── migrations/
├── create_users_table.php
├── create_personal_access_tokens_table.php
└── create_products_table.php
routes/
└── api.php
Checklist REST API Laravel Sanctum
Sebelum API digunakan, pastikan:
Sanctum sudah terpasang.
File
routes/api.phptersedia.Migration sudah dijalankan.
Tabel
personal_access_tokenstersedia.Model
UsermenggunakanHasApiTokens.Endpoint register berhasil.
Endpoint login menghasilkan token.
Token dikirim melalui Bearer Token.
Route dilindungi dengan
auth:sanctum.Endpoint CRUD berhasil diuji.
Validasi request sudah tersedia.
Logout menghapus token aktif.
APP_DEBUG=falsepada production.API menggunakan HTTPS.
Token tidak ditampilkan dalam log.
Pengembangan REST API Bersama Ovla Media
REST API dapat digunakan untuk menghubungkan berbagai sistem dalam satu lingkungan digital.
Ovla Media menyediakan layanan pengembangan dan integrasi API untuk kebutuhan seperti:
Aplikasi mobile.
Sistem Point of Sales.
Aplikasi inventory.
Sistem ERP dan CRM.
Payment gateway.
WhatsApp API.
Integrasi marketplace.
Dashboard monitoring.
Aplikasi pihak ketiga.
Sistem informasi perusahaan.
Integrasi Artificial Intelligence.
Pengembangan aplikasi Laravel custom.
API dapat dikembangkan sesuai kebutuhan autentikasi, struktur data, hak akses, keamanan, dan alur operasional perusahaan.
Kesimpulan
Laravel Sanctum menyediakan cara sederhana untuk membuat autentikasi REST API berbasis token.
Pada Laravel modern, instalasi dapat dimulai dengan:
php artisan install:api
php artisan migrate
Model User perlu menggunakan trait:
HasApiTokens
Token dibuat melalui:
$user->createToken('api-token')->plainTextToken;
Route yang membutuhkan autentikasi dilindungi menggunakan:
Route::middleware('auth:sanctum')->group(function () {
// Route yang membutuhkan token.
});
Setiap request menuju route tersebut harus menyertakan:
Authorization: Bearer TOKEN_ANDA
Accept: application/json
Dengan konfigurasi yang tepat, Sanctum dapat digunakan untuk mengamankan REST API Laravel yang diakses oleh aplikasi mobile, dashboard frontend, sistem internal, maupun layanan pihak ketiga.
Butuh implementasi untuk kebutuhan bisnis?
OVLA Media membantu pengembangan dan optimasi aplikasi web, integrasi sistem, serta solusi Laravel sesuai kebutuhan perusahaan Anda.
Artikel Terkait
Cara Membuat Audit Log Aktivitas Pengguna di Laravel
Audit log Laravel digunakan untuk mencatat aktivitas pengguna di dalam aplikasi, seperti login, logout, membuat data, mengubah data, dan menghapus data. Dengan audit log, administrator dapat mengetahui siapa yang melakukan perubahan, kapan aktivitas terjadi, dan data apa yang terpengaruh.
Cara Membuat Sinkronisasi Stok Antar-Aplikasi Menggunakan Laravel API
Sinkronisasi stok antar-aplikasi memungkinkan jumlah persediaan tetap konsisten antara sistem seperti POS, inventory, marketplace, dan gudang. Laravel API dapat digunakan untuk mengirim perubahan stok secara otomatis sehingga setiap aplikasi memiliki informasi persediaan yang lebih akurat.
Cara Membatasi Percobaan Login Menggunakan Rate Limiting Laravel
Rate limiting pada Laravel dapat digunakan untuk membatasi jumlah percobaan login dalam periode tertentu. Fitur ini membantu mengurangi risiko brute-force dengan menolak sementara permintaan login yang terlalu banyak dari pengguna atau alamat IP yang sama.