Token abilities merupakan fitur atau kemampuan tambahan ataupun batasan yang kita tetapkan pada token yang akan dibuat. Seperti menetapkan hak akses pada token yang akan memiliki ruang lingkup khusus atau cakupan tertentu yang terbatas.
if($user->tokenCan("delete")) { $user = Post::find($id); $user->delete(); return "Penghapusan berhasil!" }else{ return "Permintaan ditolak." }
Cakupan khusus yang kita berikan pada token ini, kita tetapkan pada saat melakukan permintaan untuk menghasilkan token sanctum dan akan disimpan pada database dengan kolom tersendiri.
$user->createToken('access_token', ['delete'])->plainTextToken;
MySQL [sanctum]> desc personal_access_tokens; +----------------+-----------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+-----------------+------+-----+---------+----------------+ | id | bigint unsigned | NO | PRI | NULL | auto_increment | | tokenable_type | varchar(255) | NO | MUL | NULL | | | tokenable_id | bigint unsigned | NO | | NULL | | | name | varchar(255) | NO | | NULL | | | token | varchar(64) | NO | UNI | NULL | | | abilities | text | YES | | NULL | | | last_used_at | timestamp | YES | | NULL | | | created_at | timestamp | YES | | NULL | | | updated_at | timestamp | YES | | NULL | | +----------------+-----------------+------+-----+---------+----------------+
Dalam pembuatan atau penggunaannya sendiri cukup mudah, kita hanya perlu menetapkan cakupan apa untuk token yang akan dibuat sesuai tindakan yang diberlakukan untuk token.
Untuk lebih jelas, dan bagaimana penggunaannya, mari kita coba terapkan pada autentikasi user dengan contoh tindakan pembatasan token sederhana.
Instalasi dan Konfigurasi
Mari kita buat autentikasi api user login dan registrasi dari awal dimulai dari instalasi laravel, database dan konfigurasi laravel sanctum.
Silahkan lakukan langkah-langkah di bawah ini.
//instalasi laravel laravel new sanctum
//instalasi laravel sanctum composer require laravel/sanctum php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Buka app/Http/Kernel.php
, tambahkan dibawah ini pada bagian middleware api.
'api' => [ \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ],
Buat database MySQL dan atur pada file .env
.
//.env DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=nama_database DB_USERNAME=root DB_PASSWORD=
Terakhir, lakukan migrasi.
php artisan migrate
Login dan Registrasi User
Selanjutnya kita buat sebuah controller dengan nama UserController, kemudian buat seperti dibawah ini.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\User; use Hash; use Auth; class UserController extends Controller { public function login(Request $request) { $credentials = request(["email", "password"]); if (!Auth::attempt($credentials)) { return response()->json([ "error" => "email atau password salah!", ]); } $user = $request->user(); if ($user->id === 1) { $token = $user->createToken("access_token", ["delete"]) ->plainTextToken; } else { $token = $user->createToken("access_token", ["read"]) ->plainTextToken; } return response()->json([ "user" => $user, "token" => $token, ]); } public function register(Request $request) { $user = User::create([ "name" => $request->name, "email" => $request->email, "password" => Hash::make($request->password), ]); return response()->json([ "user" => $user, ]); } }
Mari kita lihat metode login diatas, sebagai contoh disini kita buat kondisional untuk menentukan 'ability token' atau kemampuan token pada user tertentu, dalam contoh ini hanya user dengan id (1) yang memiliki kemampuan berbeda dari user lain.
if ($user->id === 1) { $token = $user->createToken("access_token", ["delete"])->plainTextToken; } else { $token = $user->createToken("access_token", ["read"])->plainTextToken; }
Route
Selanjutnya tambahkan route di bawah ini pada api.php
.
use App\Http\Controllers\UserController; Route::post("register", [UserController::class, "register"]); Route::post("login", [UserController::class, "login"]);
Setelah itu silahkan coba lakukan pendaftaran user baru lalu login menggunakan aplikasi postman.
php artisan serve
Setelah login, pada tabel Personal_access_tokens
database akan seperti di bawah ini .
MySQL [sanctum]> select id, tokenable_id, name, abilities, token from personal_access_tokens; +----+--------------+--------------+------------+------------------------------------------------------------------+ | id | tokenable_id | name | abilities | token | +----+--------------+--------------+------------+------------------------------------------------------------------+ | 1 | 1 | access_token | ["delete"] | caffc762e4507078dcc7a380a6bab9fc84f4fd2f238d7fc64785609d270f016b | | 2 | 2 | access_token | ["read"] | abf1108a64c1c94d8b53027d1a4283d7dfd524e56ae954a616106643593c014c | +----+--------------+--------------+------------+------------------------------------------------------------------+
*tokenable_id
adalah 'id' dari user.
MySQL [sanctum]> select id, name, email from users; +----+-------+----------------+ | id | name | email | +----+-------+----------------+ | 1 | user1 | [email protected] | | 2 | user2 | [email protected] | +----+-------+----------------+
Contoh Pembatasan Permintaan
Setelah token dan ability dibuat, selanjutnya kita lakukan pembatasan untuk tindakan yang akan dilakukan user.
Sebagai contoh disini kita coba melakukan penghapusan yang dilakukan user. Namun sebelumnya, kita tambahkan tabel database baru telebih dahulu dengan contoh data yang kita buat dengan laravel factory.
Silahkan lakukan langkah-langkah di bawah ini.
php artisan make:model Post php artisan make:factory PostFactory
//...create_posts_table.php public function up() { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->timestamps(); }); }
//database/factories/PostFactory.php public function definition() { return [ "title" => $this->faker->sentence(), ]; }
//database/seeders/DatabaseSeeder.php public function run() { \App\Models\Post::factory(10)->create(); }
//jalankan migrasi php artisan migrate --seed
Setelah melakukan migrasi sekaligus seeding, kita telah memiliki data contoh pada tabel 'posts'.
MySQL [sanctum]> select id, title from posts; +----+-----------------------------------------------------------------------+ | id | title | +----+-----------------------------------------------------------------------+ | 1 | Repellat voluptatem illum qui expedita reprehenderit sunt. | | 2 | Dolorum in voluptatibus et id. | | 3 | Et voluptatem delectus at delectus perspiciatis animi optio. | | 4 | Non beatae cupiditate nisi culpa aut sed nam libero. | | 5 | Modi tempore et natus maiores commodi minus doloribus veniam. | | 6 | Id ullam cum ipsum sequi. | | 7 | Tempora ipsam vel vel et magni iusto. | | 8 | Id omnis possimus reiciendis nostrum est. | | 9 | Quod voluptatibus in aliquid molestiae reiciendis ducimus temporibus. | | 10 | Quaerat est est nesciunt est est ex. | +----+-----------------------------------------------------------------------+
Selanjutnya kita buat metode penghapusan data. Silahkan tambahkan di bawah ini pada UserController.php
.
... use App\Models\User; ... public function singlePost($id) { $post = Post::find($id); return response()->json($post); } public function deletePost($id, Request $request) { $user = $request->user(); if ($user->tokenCan("delete")) { $post = Post::find($id); $post->delete(); return "Penghapusan berhasil."; } return "Permintaan ditolak!"; }
Pada metode deletePost()
diatas, kita gunakan metode tokenCan()
untuk memastikan bahwa user yang telah melewati otorisasi token memiliki ability 'delete' untuk dapat menghapus 'post'.
Selanjutnya tambahkan route di bawah ini pada api.php
.
Route::group(["middleware" => "auth:sanctum"], function () { Route::get("user", [UserController::class, "user"]); Route::get("post/{id}", [UserController::class, "singlePost"]); Route::delete("post/delete/{id}", [UserController::class, "deletePost"]); });
Sampai disini tinggal mencobanya. Silahkan buat request baru pada postman, coba melakukan penghapusan.
MySQL [sanctum]> select tokenable_id, name, abilities from personal_access_tokens; +--------------+--------------+------------+ | tokenable_id | name | abilities | +--------------+--------------+------------+ | 1 | access_token | ["delete"] | | 2 | access_token | ["read"] | +--------------+--------------+------------+
User 1:
MySQL [sanctum]> select id, title from posts; +----+-----------------------------------------------------------------------+ | id | title | +----+-----------------------------------------------------------------------+ | 1 | Repellat voluptatem illum qui expedita reprehenderit sunt. | | 2 | Dolorum in voluptatibus et id. | | 3 | Et voluptatem delectus at delectus perspiciatis animi optio. | | 4 | Non beatae cupiditate nisi culpa aut sed nam libero. | | 5 | Modi tempore et natus maiores commodi minus doloribus veniam. | | 6 | Id ullam cum ipsum sequi. | | 7 | Tempora ipsam vel vel et magni iusto. | | 8 | Id omnis possimus reiciendis nostrum est. | | 9 | Quod voluptatibus in aliquid molestiae reiciendis ducimus temporibus. | +----+-----------------------------------------------------------------------+
User 2:
Selesai
Sampai disini kita telah berhasil menggunakan ability token untuk memberi batasan atau kemampuan khusus pada token. Silahkan dicoba dan dikembangkan.