Autentikasi dengan Laravel Sanctum & Fortify untuk SPA

Kita sama - sama tau, begitu banyak first party package untuk melakukan autentikasi, seperti breeze, ui, jetstream. Nah jetstream sendiri juga menggunakan fortify sebagai api auth nya, namun, jika kita tidak ingin menggunakan jetstream melainkan ingin memakai fortify nya saja juga bisa, terlebih lagi, kita bisa turn off view nya yang by default bisa kita tentukan dalam AppServiceProvider, kali ini saya akan menganggap bahwa Anda ingin memakai fortify sebagai api saja, dan untuk view auth nya menggunakan spa yang telah Anda punya.

Pertama sekali, silahkan install laravel nya dengan composer ataupun laravel command cli yang telah di install di machine Anda.

laravel new fortify-api

Setelah itu, silahakan masuk kedalam folder fortify-api, kemudian install fortify nya dengan cara seperti ini.

fortify-api > composer require laravel/fortify

Jika sudah, langsung aja publish vendor dari fortify tersebut dengan artisan command

fortify-api > php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"

Jika sudah, silahkan masukkan sanctum middleware nya kedalam app/Http/Kernel.php tepat pada api key.

'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    'throttle:api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

Setelah itu, pastikan FortifyServiceProvider telah terdaftar di config/app.php, karena jika tidak, dia tidak akan dikenali. Buka config/app.php

/*
 * Application Service Providers...
 */

App\Providers\FortifyServiceProvider::class,

Setelah itu, silahkan buat satu seeder untuk user dengan artisan command seperti berikut.

fortify-api > php artisan make:seed UserSeeder

Silahkan buka filenya tepat pada database/seeders/UserSeeder.php dan masukkan satu user saja tepat pada run method seperti berikut.

public function run()
{
    DB::table('users')->insert([
        'name' => 'Irsyad A. Panjaitan',
        'email' => 'irsyad@parsinta.com',
        'email_verified_at' => null,
        'password' => bcrypt('password'),
    ]);
}

Setelah itu, pastikan Anda sudah setup database sesuai dengan konfigurasi yang Anda punya, buka file .env.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=fortify_api
DB_USERNAME=root
DB_PASSWORD=

Jika sudah, maka kita bisa lanjut untuk melakukan migrate sekalian memasukkan seedernya dengan cara.

fortify-api > php artisan migrate --seed

Lanjut, buka kembali .env file, dan setup sanctum dan juga mailnya.

# Sanctum
SANCTUM_STATEFUL_DOMAINS=localhost:3000
SPA_URL=http://localhost:3000
SESSION_DOMAIN=localhost

# Mail
MAIL_FROM_ADDRESS=noreply@domain.com

Silahkan sesuaikan port SPA yang Anda punyai dengan url yang ada di atas. Disini saya menganggap Anda menggunakan react, jadi saya berasumsi portnya 3000, jika Anda menggunakan vue, itu seharusnya 8080 jika tidak di modifikasi.

Lanjut, silahkan buka file konfig untuk cors yang by default sudah diberi sewaktu kita install laravel config/cors.php

'paths' => [
  'api/*',
  'login',
  'logout',
  'register',
  'user/password',
  'forgot-password',
  'reset-password',
  'sanctum/csrf-cookie',
  'user/profile-information',
  'email/verification-notification',
],

Masih tetap di file yang sama, silahkan scroll kebawah dan pastikan supports_credentials nya turn on seperti berikut.

'supports_credentials' => true,

Nah, sekarang waktunya kita setup fortify itu sendiri yang ada di config/fortify.php. Untuk default redirect nya kita akan masukkan url spa kita yang sudah setup didalam .env tadi seperti berikut.

'home' => env('SPA_URL') . '/dashboard',

Jangan lupa, karena view auth nya kita ingin dari SPA, maka kita akan turn off view nya seperti berikut.

'views' => false,

Selanjutnya, silahkan uncomment fitur yang ingin Anda pakai di fortify itu sendiri.

'features' => [
    Features::registration(),
    Features::resetPasswords(),
    Features::emailVerification(),
    Features::updateProfileInformation(),
    Features::updatePasswords(),
],

Jika sudah, kita bisa lanjut untuk edit file middleware RedirectIfAuthenticated yang ada di app/Http/Middleware/RedirectIfAuthenticated.php dan modifikasi loop untuk guard yang ada di dalam method handle tersebut seperti berikut.

foreach ($guards as $guard) {
    if (Auth::guard($guard)->check()) {
        if ($request->expectsJson()) {
            return response()->json(['error' => 'You already authenticated.'], 200);
        }
        return redirect(RouteServiceProvider::HOME);
    }
}

Apa yang kita tambahkan adalah, ketika request mengharapkan json, kita akan return json dengan pesan You already authenticated.

Masih didalam folder middleware, silahkan buka file Authenticate.php dan buat default nya ke SPA url yang kita punya jika request tidak di dapat dari json.

protected function redirectTo($request)
{
    if (! $request->expectsJson()) {
        return url(env('SPA_URL') . '/login');
    }
}

Untuk mengaktifkan email, ada yang perlu Anda tambahkan pada model User, silahkan buka filenya di app/Models/User.php dan implementasikan MustVerifyEmail ke dalam kelas User tersebut seperti berikut.

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;
    // ...
}

Next, kita setup untuk reset password, apa yang kita lakukan disini hanyalah memodifikasi url default yang diberi laravel itu sendiri ke dalam SPA kita. silahkan buka AuthServiceProvider yang ada di App\Providers\AuthServiceProvider.php dan tepat pada boot method.

public function boot()
{
    ResetPassword::createUrlUsing(function ($user, string $token) {
        return env('SPA_URL') . '/reset-password?token=' . $token;
    });
}

Jangan lupa untuk memasukkan ResetPassword class kedalam AuthServiceProvider seperti berikut.

namespace App\Providers;
use Illuminate\Auth\Notifications\ResetPassword;
...

Jika sudah, maka kita hampir selesai, silahkan buka route api.php dan masukkan authenticated user didalam auth:sanctum seperti berikut.

use Illuminate\Http\Request;

Route::middleware('auth:sanctum')->get('/users/{user}', function (Request $request) {
    return $request->user();
});

Nah jika sudah, harusnya semua sudah selesai, jika kalian ingin tau bagaimana kerja dengan breeze, kalian bisa lihat disini.

Irsyad A. Panjaitan

Irsyad A. Panjaitan

    Published 06 April
  •  
  • Fillin:
  • Laravel
Irsyad Notes Since 1987 ™