Laravel dikenal karena fleksibilitas dan kemudahan penggunaannya. Salah satu fitur unggulannya adalah sistem otentikasi (authentication) yang mudah diimplementasikan. Namun, bagaimana jika Anda memiliki kebutuhan otentikasi yang berbeda dari sistem bawaan Laravel? Misalnya, Anda ingin menggunakan API eksternal, database legacy, atau bahkan sistem otentikasi khusus yang sama sekali berbeda. Jawabannya adalah membuat custom authentication driver di Laravel.
Artikel ini akan memandu Anda langkah demi langkah dalam membuat custom authentication driver di Laravel, sehingga Anda dapat mengintegrasikan sistem login yang berbeda sesuai kebutuhan proyek Anda. Kami akan membahas konsep dasar, memberikan contoh kode yang jelas, dan menjelaskan setiap langkah prosesnya. Mari kita mulai!
1. Mengapa Membuat Custom Authentication Driver di Laravel?
Sebelum kita terjun ke kode, mari kita pahami dulu mengapa kita mungkin memerlukan custom authentication driver. Meskipun Laravel menyediakan sistem otentikasi yang solid, ada beberapa skenario di mana kita perlu menyesuaikannya:
- Integrasi Sistem Legacy: Jika Anda bekerja dengan aplikasi yang sudah ada (legacy) dengan sistem otentikasi yang berbeda, custom driver adalah cara terbaik untuk mengintegrasikannya dengan Laravel tanpa mengubah kode yang ada.
- Otentikasi Berbasis API: Anda mungkin ingin menggunakan API pihak ketiga untuk mengotentikasi pengguna. Custom driver memungkinkan Anda berinteraksi dengan API ini.
- Database yang Tidak Standar: Laravel secara default mengasumsikan struktur tabel pengguna yang standar. Jika Anda menggunakan database dengan skema yang berbeda, custom driver diperlukan.
- Sistem Otentikasi Khusus: Terkadang, Anda mungkin memiliki kebutuhan otentikasi yang sangat spesifik yang tidak dapat dipenuhi oleh sistem otentikasi standar.
- Keamanan Tingkat Lanjut: Anda dapat menerapkan logika otentikasi yang lebih kompleks dan aman, seperti multi-factor authentication (MFA) atau otentikasi biometrik.
Dengan membuat custom authentication driver di Laravel, Anda memiliki kontrol penuh atas proses otentikasi dan dapat menyesuaikannya sesuai kebutuhan proyek Anda.
2. Konsep Dasar: Memahami Authentication Driver di Laravel
Sebelum membuat custom authentication driver di Laravel, penting untuk memahami komponen-komponen kunci yang terlibat:
- Auth Manager: Komponen inti yang mengelola semua authentication driver. Ini adalah titik masuk untuk mengakses dan menggunakan sistem otentikasi.
- Authentication Driver: Implementasi spesifik dari logika otentikasi. Driver bertanggung jawab untuk memvalidasi kredensial pengguna, mengambil informasi pengguna, dan menyimpan sesi pengguna.
- User Provider: Bertanggung jawab untuk mengambil informasi pengguna dari sumber data (database, API, dll.). Biasanya, User Provider berinteraksi dengan model Eloquent.
- Guard: Menentukan bagaimana pengguna diotentikasi dan dilindungi. Guard menggunakan authentication driver dan user provider untuk memverifikasi identitas pengguna.
Secara sederhana, alurnya adalah:
- Guard menerima permintaan otentikasi.
- Guard menggunakan authentication driver untuk memvalidasi kredensial.
- Authentication driver menggunakan user provider untuk mengambil informasi pengguna.
- Jika kredensial valid, Guard menetapkan pengguna yang diotentikasi ke sesi.
3. Langkah-Langkah Membuat Custom Authentication Driver: Studi Kasus Otentikasi dengan API Eksternal
Mari kita ilustrasikan proses membuat custom authentication driver di Laravel dengan studi kasus: otentikasi menggunakan API eksternal. Bayangkan Anda memiliki API yang menyediakan endpoint untuk memvalidasi kredensial pengguna. Kita akan membuat driver yang berinteraksi dengan API ini.
Langkah 1: Membuat User Provider
Pertama, kita perlu membuat user provider yang dapat mengambil informasi pengguna dari API eksternal. Buat file app/Providers/ApiUserProvider.php dengan konten berikut:
<?php
namespace AppProviders;
use IlluminateContractsAuthAuthenticatable;
use IlluminateContractsAuthUserProvider;
use IlluminateSupportFacadesHttp;
class ApiUserProvider implements UserProvider
{
protected $model;
public function __construct(string $model)
{
$this->model = $model;
}
public function retrieveById($identifier)
{
$model = $this->getModel();
//Asumsi API mengembalikan data seperti model Eloquent
$response = Http::get("https://api-eksternal.com/users/{$identifier}");
if ($response->successful()) {
$userData = $response->json();
return new $model((array) $userData); //Instantiate model
}
return null;
}
public function retrieveByToken($identifier, $token)
{
// Opsi: Implementasi untuk remember me functionality
return null;
}
public function updateRememberToken(Authenticatable $user, $token)
{
// Opsi: Implementasi untuk remember me functionality
}
public function retrieveByCredentials(array $credentials)
{
$model = $this->getModel();
// Sesuaikan URL dan parameter API sesuai kebutuhan
$response = Http::post('https://api-eksternal.com/login', $credentials);
if ($response->successful()) {
$userData = $response->json();
if (isset($userData['user'])) { // Asumsi API mengembalikan data user di dalam array 'user'
return new $model((array) $userData['user']); // Instantiate model
} else {
return new $model((array) $userData); // Jika API langsung mengembalikan data user
}
}
return null;
}
public function validateCredentials(Authenticatable $user, array $credentials)
{
// Kita sudah memvalidasi kredensial di retrieveByCredentials
// Cukup bandingkan hash password jika API tidak menyediakan validasi langsung
// atau selalu return true jika validasi dilakukan di API.
return true;
}
protected function getModel()
{
$class = '\'.ltrim($this->model, '\');
return $class;
}
}
Penjelasan:
retrieveById(): Mengambil pengguna berdasarkan ID.retrieveByToken(): Mengambil pengguna berdasarkan token (untuk fitur “remember me”).updateRememberToken(): Memperbarui token “remember me”.retrieveByCredentials(): Mengambil pengguna berdasarkan kredensial (username/email dan password). Ini adalah inti dari validasi login. Kita menggunakanHttp::post()untuk mengirim kredensial ke API eksternal.validateCredentials(): Memvalidasi kredensial terhadap pengguna yang ada. Dalam kasus ini, karena validasi sudah dilakukan oleh API eksternal diretrieveByCredentials, kita hanya mengembalikantrue. Jika API tidak melakukan validasi password, Anda bisa membandingkan hash password di sini.getModel(): Mengembalikan nama model yang digunakan.
Langkah 2: Membuat Authentication Driver
Selanjutnya, kita buat authentication driver yang menggunakan user provider yang baru kita buat. Buat file app/Auth/ApiAuthGuard.php dengan konten berikut:
<?php
namespace AppAuth;
use IlluminateAuthGuardHelpers;
use IlluminateContractsAuthAuthenticatable;
use IlluminateContractsAuthGuard;
use IlluminateContractsAuthUserProvider;
use IlluminateHttpRequest;
class ApiAuthGuard implements Guard
{
use GuardHelpers;
protected $provider;
protected $request;
public function __construct(UserProvider $provider, Request $request)
{
$this->provider = $provider;
$this->request = $request;
}
public function user()
{
if (! is_null($this->user)) {
return $this->user;
}
$user = null;
// Coba otentikasi menggunakan token API (misalnya, dari header)
$token = $this->request->header('X-API-Token');
if (! empty($token)) {
// Asumsikan API memerlukan ID pengguna bersama dengan token
$userId = $this->request->header('X-User-ID'); // Contoh, sesuaikan sesuai API
$user = $this->provider->retrieveByToken($userId, $token); // Perlu implementasi di UserProvider jika menggunakan token
}
return $this->user = $user;
}
public function validate(array $credentials = [])
{
$user = $this->provider->retrieveByCredentials($credentials);
if ($user) {
return true;
}
return false;
}
public function attempt(array $credentials = [])
{
$user = $this->provider->retrieveByCredentials($credentials);
if ($user) {
$this->setUser($user);
return true;
}
return false;
}
public function setRequest(Request $request)
{
$this->request = $request;
return $this;
}
}
Penjelasan:
__construct(): Menerima UserProvider dan Request sebagai argumen.user(): Mencoba mengambil pengguna yang sudah terotentikasi. Dalam contoh ini, kita mencoba mengotentikasi menggunakan token API yang dikirimkan melalui header. Anda bisa menyesuaikan logika ini sesuai dengan kebutuhan API Anda. Jika tidak ada token atau validasi gagal, fungsi ini mengembalikannull.validate(): Memvalidasi kredensial yang diberikan. Driver menggunakanretrieveByCredentials()dari UserProvider untuk memverifikasi kredensial.attempt(): Mencoba mengotentikasi pengguna dengan kredensial yang diberikan. Jika berhasil, pengguna diatur sebagai pengguna yang diotentikasi.setRequest(): Mengatur request HTTP.
Langkah 3: Mendaftarkan Driver dan Provider
Kita perlu mendaftarkan driver dan provider kita ke dalam sistem otentikasi Laravel. Buka file config/auth.php dan modifikasi array providers dan guards:
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'api', // Ubah default guard jika ingin menggunakan API authentication secara default
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define multiple authentication "guards" for your application.
| The guard determines which driver should be used to authenticate users.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'api', // Tambahkan custom driver
'provider' => 'api', // Tambahkan custom provider
],
],
/*
|--------------------------------------------------------------------------
| Authentication Providers
|--------------------------------------------------------------------------
|
| Next, you may define multiple authentication "providers" for your
| application. The provider tells Laravel where to look for your users.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => AppModelsUser::class,
],
'api' => [
'driver' => 'api', // Tambahkan custom driver
'model' => AppModelsUser::class, // Ganti dengan model yang sesuai
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model. Each configuration contains the name
| of the model that represents your users and the table where pass
| words are stored.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before password confirmation
| times out and the user is prompted to re-enter their password.
|
*/
'password_timeout' => 10800,
];
Kemudian, daftarkan provider ApiUserProvider di app/Providers/AuthServiceProvider.php:
<?php
namespace AppProviders;
use AppAuthApiAuthGuard;
use AppProvidersApiUserProvider;
use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider;
use IlluminateSupportFacadesAuth;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
// 'AppModelsModel' => 'AppPoliciesModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::extend('api', function ($app, $name, array $config) {
// Resolving the user provider instance
$provider = Auth::createUserProvider($config['provider']);
return new ApiAuthGuard($provider, $app['request']);
});
Auth::provider('api', function ($app, array $config) {
// Return an instance of ApiUserProvider...
return new ApiUserProvider($config['model']);
});
}
}
Penjelasan:
config/auth.php: Kita menambahkan providerapidan guardapidengan konfigurasi yang sesuai. Perhatikan bahwa model yang digunakan di providerapiharus sesuai dengan format data yang dikembalikan oleh API eksternal. Anda mungkin perlu membuat model Eloquent yang sesuai atau menggunakanstdClassjika data tidak sesuai dengan struktur model Eloquent.app/Providers/AuthServiceProvider.php: Kita mendaftarkan extension untuk driverapidan providerapi. Ini memberitahu Laravel bagaimana membuat instance dari driver dan provider kita.
Langkah 4: Membuat Model User (Jika Belum Ada)
Jika Anda belum memiliki model AppModelsUser, buatlah. Pastikan struktur atribut model ini sesuai dengan data yang dikembalikan oleh API eksternal. Anda mungkin perlu menambahkan atau mengubah properti model agar sesuai.
<?php
namespace AppModels;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'api_id', // Tambahkan 'api_id' jika API menggunakan ID yang berbeda
// Atribut lain yang dikembalikan oleh API
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
// Sesuaikan dengan API response
public function getAuthIdentifierName()
{
return 'api_id'; // Sesuaikan dengan nama field ID di API
}
public function getAuthIdentifier()
{
return $this->{$this->getAuthIdentifierName()};
}
}
Penting: Perhatikan metode getAuthIdentifierName() dan getAuthIdentifier(). Jika API Anda menggunakan ID yang berbeda dari kolom id standar, Anda perlu menyesuaikan metode ini agar Laravel dapat mengidentifikasi pengguna dengan benar.
4. Menggunakan Custom Authentication Driver
Sekarang kita sudah berhasil membuat custom authentication driver di Laravel, saatnya untuk menggunakannya. Anda dapat menggunakan guard api di controller, middleware, atau blade templates.
Contoh Controller:
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use IlluminateSupportFacadesAuth;
class ApiAuthController extends Controller
{
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::guard('api')->attempt($credentials)) {
$user = Auth::guard('api')->user();
// Buat token API (jika diperlukan) dan kembalikan ke client
$token = 'generated_api_token'; // Ganti dengan logika pembuatan token Anda
return response()->json(['message' => 'Login berhasil', 'token' => $token, 'user' => $user]);
}
return response()->json(['message' => 'Login gagal'], 401);
}
public function profile(Request $request)
{
// Memastikan pengguna sudah terotentikasi dengan guard 'api'
$user = Auth::guard('api')->user();
if ($user) {
return response()->json(['message' => 'Profil pengguna', 'user' => $user]);
}
return response()->json(['message' => 'Tidak terotentikasi'], 401);
}
public function logout(Request $request)
{
Auth::guard('api')->logout(); //Logika logout mungkin perlu disesuaikan
return response()->json(['message' => 'Logout berhasil']);
}
}
Penjelasan:
- Kita menggunakan
Auth::guard('api')untuk mengakses guard yang menggunakan driverapi. attempt()mencoba mengotentikasi pengguna.user()mengembalikan pengguna yang sudah terotentikasi.
Contoh Middleware:
Anda dapat membuat middleware untuk melindungi rute API Anda:
<?php
namespace AppHttpMiddleware;
use Closure;
use IlluminateSupportFacadesAuth;
class ApiAuthenticate
{
/**
* Handle an incoming request.
*
* @param IlluminateHttpRequest $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (Auth::guard('api')->check()) {
return $next($request);
}
return response()->json(['message' => 'Unauthorized'], 401);
}
}
Kemudian, daftarkan middleware ini di app/Http/Kernel.php dan gunakan di rute API Anda.
5. Tips dan Trik dalam Membuat Custom Authentication Driver
Berikut beberapa tips dan trik yang perlu diingat saat membuat custom authentication driver di Laravel:
- Fokus pada Kebutuhan: Pastikan driver Anda benar-benar memenuhi kebutuhan otentikasi proyek Anda. Jangan membuat driver yang terlalu kompleks jika solusi yang lebih sederhana sudah cukup.
- Keamanan: Perhatikan keamanan! Pastikan kredensial pengguna disimpan dengan aman dan semua komunikasi dienkripsi.
- Dokumentasi API: Pahami dengan baik dokumentasi API eksternal yang Anda gunakan. Pastikan Anda mengirimkan data dengan format yang benar dan menangani respons dengan benar.
- Pengujian: Uji driver Anda secara menyeluruh. Pastikan driver berfungsi dengan benar dalam berbagai skenario, termasuk kasus kesalahan.
- Error Handling: Implementasikan penanganan kesalahan yang baik. Tangkap semua pengecualian yang mungkin terjadi dan berikan pesan kesalahan yang informatif.
- Cache: Jika memungkinkan, gunakan cache untuk mengurangi beban pada API eksternal.
- Logging: Log semua aktivitas otentikasi untuk tujuan debugging dan audit.
6. Kesimpulan: Fleksibilitas Otentikasi dengan Custom Driver di Laravel
Membuat custom authentication driver di Laravel memungkinkan Anda untuk mengintegrasikan sistem otentikasi yang berbeda dan memenuhi kebutuhan unik proyek Anda. Dengan memahami konsep dasar dan mengikuti langkah-langkah yang dijelaskan dalam artikel ini, Anda dapat dengan mudah membuat driver otentikasi yang disesuaikan dan mengoptimalkan keamanan dan fleksibilitas aplikasi Laravel Anda. Ingatlah untuk selalu fokus pada keamanan, pengujian, dan penanganan kesalahan untuk memastikan driver Anda berfungsi dengan benar dan aman. Selamat mencoba!









