Laravel Sanctum adalah package yang disediakan laravel untuk menangani proses autentikasi dan otorisasi pengguna.
Layaknya jwt yang dapat menghasilkan token, laravel Sanctum juga demikian, namun token yang dihasilkan berbeda, dan Sanctum tidak menggunakan implementasi OAuth2 seperti halnya laravel Passport.
Laravel Sanctum merupakan cookie based atau autentikasi sesi berbasis cookie, dimana autentikasi atau otorisasi ditangani melalui cookie.
Untuk contoh dan cara penggunaanya, mari kita buat bersama.
Instalasi Laravel & Pengaturan Database
Langkah awal, telebih dahulu kita download laravel dan mengatur database.
laravel new sanctum
Silahkan buat database mysql baru dan atur pada file .env
.
//.env DB_DATABASE=sanctum DB_USERNAME=root DB_PASSWORD=
Instalasi Laravel Sanctum
Selanjutnya kita instal package sanctum menggunakan composer.
composer require laravel/sanctum
Setelah instalasi selesai, selanjutnya kita buat file konfigurasi sanctum dengan perintah di bawah ini.
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
File konfigurasi yang terbuat berada pada direktori config dengan nama sanctum.php. Selanjutnya kita lakukan migrasi untuk membuat tabel database.
php artisan migrate
Setelah migrasi selesai, jika dilihat pada database akan terbuat beberapa tabel seperti dibawah; laravel sanctum memiliki sebuah tabel tersendiri untuk menyimpan token API pengguna dengan beberapa kolom didalamnya seperti nama token, model terkait, id pengguna, dan lainnya.
MariaDB [sanctum]> show tables; +------------------------+ | Tables_in_sanctum | +------------------------+ | failed_jobs | | migrations | | password_resets | | personal_access_tokens | | users | +------------------------+ 5 rows in set (0.002 sec)
Konfigurasi
Kita lanjutkan dengan melakukan beberapa pengaturan atau konfirgurasi yang di perlukan.
Permintaan Akses Token pada Model
Buka model User.php, tambahkan HasApiTokens
seperti di bawah ini.
//User.php use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable { use HasFactory, Notifiable, HasApiTokens; ... }
Menambahkan Middleware
Buka app/Http/Kernel.php, tambahkan middleware EnsureFrontendRequestsAreStateful
pada api
middleware seperti di bawah ini.
'api' => [ \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ],
Mengatur CORS (Cross-Origin Resource Sharing)
Buka config/cors.php, atur cors paths
dan supports_credentials
seperti di bawah ini.
'paths' => ['api/*', '/login', 'sanctum/csrf-cookie'], ... 'supports_credentials' => true,
Ubah Driver Sesi
Kita ubah driver default sesi. Buka .env
, pada SESSION_DRIVER
ubah file
menjadi cookie
seperti dibawah ini.
SESSION_DRIVER=cookie
Memabahkan Stateful Domain
Kita tambahkan domain untuk identifikasi cookie sesi pada permintaan yang dibuat. Untuk domain saat ini kita gunakan localhost.
Buka .env
, tambahkan di bawah ini.
SANCTUM_STATEFUL_DOMAINS=localhost
Menambahkan User
Kita lanjutkan dengan menambahkan user baru pada database, menyediakan user untuk proses login pengguna. Kita buat menggunakan seeder.
php artisan make:seeder UserSeeder
//database/seeders/UserSeeder.php public function run() { \DB::table('users')->insert([ 'name' => 'user', 'email' => '[email protected]', 'password' => bcrypt('12345678'), 'created_at' => new \DateTime, 'updated_at' => null, ]); }
//database/seeders/DatabaseSeeder.php public function run() { $this->call([ UserSeeder::class, ]); }
php artisan db:seed
MariaDB [sanctum]> select id, name, email from users; +----+------+---------------+ | id | name | email | +----+------+---------------+ | 1 | user | [email protected] | +----+------+---------------+ 1 row in set (0.000 sec)
Sampai disini kita kita telah melakukan konfigurasi dan memiliki user untuk kita gunakan saat login.
Membuat Controller
Selanjutnya kita buat sebuah controller dan membuat request untuk login pengguna.
php artisan make:controller LoginController
Buka LoginController.php, buat seperti dibawah ini.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Auth; class LoginController extends Controller { public function store(Request $request) { $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], ]); $status = 401; $response = [ 'error' => 'Proses masuk gagal!. Silahkan coba kembali.', ]; if (Auth::attempt($credentials)) { $status = 200; $token = $request->user()->createToken('access_token')->plainTextToken; $response = [ 'access_token' => $token, 'token_type' => 'Bearer', ]; } return response()->json($response, $status); } }
Kemudian tambahkan route dibawah ini pada api.php.
use App\Http\Controllers\LoginController; Route::post('/login', [LoginController::class, 'store']);
Postman: API Testing
Kita ke tahap pengujian, melakukan login dan menggunakan token untuk otorisasi. Silahkan buka aplikasi postman dan buat request baru seperti gambar di bawah ini.
Ketika berhasil login, permintaan token akan dibuat, dan tabel personal_access_token
pada database akan menyimpan token API pengguna yang diubah ke hash SHA-256 seperti di bawah ini.
MariaDB [sanctum]> select id, tokenable_type, tokenable_id, name, token from personal_access_tokens; +----+-----------------+--------------+--------------+------------------------------------------------------------------+ | id | tokenable_type | tokenable_id | name | token | +----+-----------------+--------------+--------------+------------------------------------------------------------------+ | 1 | App\Models\User | 1 | access_token | dd6ffd339250c3695900cb2c851cc6faa96da01404643dcdb69f893dcdfcd3d8 | +----+-----------------+--------------+--------------+------------------------------------------------------------------+ 2 rows in set (0.001 sec)
Proteksi Route
Sekarang kita coba menggunakan middeleare sanctum untuk proteksi route yang ingin kita lindungi -- permintaan yang dibuat harus melawati proses autentikasi.
Sebagai contoh, mari kita buat permintaan untuk menampilkan objek user. Buka api.php, buat seperti di bawah ini.
Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); });
Kemudian buka kembali postman, buat request baru seperti di bawah ini.
- Method: GET
- Url: http://localhost:8000/api/user
- Header: Accept | application/json
Sekarang token dari respon login tadi kita gunakan untuk otorisasi. Pada menu Authorization buat seperti di bawah ini.
- Type: Bearer Token
- Token: < token >
Token diterima dan permintaan ke obojek user berhasil.
Membuat Halaman Login
Selanjutnya mari kita coba untuk login melalui browser. Kita buat sebuah halaman login dengan form html.
Langkah pertama silahkan buka LoginController.php, buat seperti di bawah ini.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\User; use Auth; class LoginController extends Controller { public function create() { return view('login'); } public function store(Request $request){ $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], ]); if (!Auth::attempt($credentials)) { return back()->withErrors([ 'email' => 'Proses masuk gagal!. Silahkan coba kembali.', ]); } $request->user()->createToken('access_token')->plainTextToken; $request->session()->regenerate(); return back(); } public function user(Request $request) { return $request->user(); } public function destroy(Request $request) { $request->user()->tokens()->where('tokenable_id', Auth::user()->id)->delete(); Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return back(); } }
Kemudian buat file login.blade.php pada direktori views dan copas html di bawah ini.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login</title> </head> <body> @if ($errors->any()) <div class="alert alert-css"> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif <form method="POST" action="{{ route('store')}}"> @csrf <input type="text" name="email" placeholder="email"> <input type="password" name="password" placeholder="password"> <button type="submit">Submit</button> </form> @if (Auth::check()) <p>Login berhasil:</p> <p> {{ Auth::user() }}</p> <form method="POST" action="{{ route('logout')}}"> @csrf <button type="submit">Logout</button> </form> @endif </body> </html>
Lalu tambahkan route di bawah ini pada web.php.
use App\Http\Controllers\LoginController; Route::get('/login', [LoginController::class, 'create'])->name('login'); Route::post('/store', [LoginController::class, 'store'])->name('store'); Route::get('/user', [LoginController::class, 'user'])->middleware('auth:sanctum'); Route::post('/logout', [LoginController::class, 'destroy'])->name('logout');
Sampai disini tinggal mencobanya di browser. Silahkan coba langkah-langkah seperti di bawah ini.
- Buka halaman login: http://localhost:8000/login dan masuk dengan email dan password yang telah dibuat.
- Buka http://localhost:8000/user dalam keadaan login atau tanpa login untuk menguji proteksi route.
- Submit form dengan value kosong untuk memunculkan validasi.
- Login dengan email atau password yang salah untuk memunculkan pesan kesalahan.
Selesai
Demikian contoh dan cara menggunakan laravel Sanctum, kita sampai disini. Silahkan dicoba dan dikembangkan.