Tutorial 24 Jul 2026 43 Kali Dibaca

Cara Membuat REST API Laravel Menggunakan Sanctum dari Awal

Gugun Nurdiansyah
Penulis
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:

MetodeFungsi
GETMengambil data
POSTMenambahkan data
PUT atau PATCHMemperbarui data
DELETEMenghapus 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:

  1. REST API sederhana.

  2. Aplikasi Android atau iOS.

  3. Integrasi aplikasi pihak ketiga.

  4. Dashboard berbasis React atau Vue.

  5. Sistem yang membutuhkan personal access token.

  6. 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:

MetodeEndpointFungsiAkses
POST/api/registerMembuat akunPublik
POST/api/loginLogin dan membuat tokenPublik
GET/api/userMengambil pengguna aktifToken
POST/api/logoutMenghapus token aktifToken
GET/api/productsMenampilkan produkToken
POST/api/productsMenambahkan produkToken
GET/api/products/{id}Detail produkToken
PUT/api/products/{id}Memperbarui produkToken
DELETE/api/products/{id}Menghapus produkToken

Persiapan Project

Pastikan komputer atau server telah memiliki:

  1. PHP sesuai kebutuhan versi Laravel.

  2. Composer.

  3. MySQL atau MariaDB.

  4. Extension PHP yang dibutuhkan Laravel.

  5. 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:

  1. Menampilkan daftar produk.

  2. Menambahkan produk.

  3. Menampilkan detail produk.

  4. Memperbarui produk.

  5. 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:

  1. Sanctum sudah terpasang.

  2. File routes/api.php tersedia.

  3. Migration sudah dijalankan.

  4. Tabel personal_access_tokens tersedia.

  5. Model User menggunakan HasApiTokens.

  6. Endpoint register berhasil.

  7. Endpoint login menghasilkan token.

  8. Token dikirim melalui Bearer Token.

  9. Route dilindungi dengan auth:sanctum.

  10. Endpoint CRUD berhasil diuji.

  11. Validasi request sudah tersedia.

  12. Logout menghapus token aktif.

  13. APP_DEBUG=false pada production.

  14. API menggunakan HTTPS.

  15. 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:

  1. Aplikasi mobile.

  2. Sistem Point of Sales.

  3. Aplikasi inventory.

  4. Sistem ERP dan CRM.

  5. Payment gateway.

  6. WhatsApp API.

  7. Integrasi marketplace.

  8. Dashboard monitoring.

  9. Aplikasi pihak ketiga.

  10. Sistem informasi perusahaan.

  11. Integrasi Artificial Intelligence.

  12. 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.

Konsultasi & Solusi

Butuh implementasi untuk kebutuhan bisnis?

OVLA Media membantu pengembangan dan optimasi aplikasi web, integrasi sistem, serta solusi Laravel sesuai kebutuhan perusahaan Anda.

#Laravel #REST API Laravel #Laravel Sanctum #API Laravel #Autentikasi API #Bearer Token Laravel #Personal Access Token #Laravel API Authentication #CRUD API Laravel #Route API Laravel #Auth Sanctum #Register API Laravel #Login API Laravel #Logout API Laravel #PHP Artisan #Laravel Development #Laravel Developer Indonesia #Web Development #Mobile API #API Integration #Ovla Media #Jasa Laravel #Jasa Pembuatan REST API #Jasa Integrasi API
Beranda Produk Artikel
Konsultasi
OVLA

Navigasi Utama

Hubungi Kami

Mulai Konsultasi Sekarang