Autentikasi & Keamanan

Konfigurasi

Laravel menargetkan implementasi proses autentikasi yg sederhana. Faktanya, hampir semua telah dikonfigurasi untuk Anda sejak awal. File konfigurasi autentikasi berlokasi pada file app/config/auth.php, dimana berisi berbagai opsi lengkap dgn dokumentasi untuk mengatur tingkah laku fasilitas autentikasi.

Secara default, Laravel telah memiliki sebuah model User di dalam direktori app/models yg dapat dipakai dgn Eloquent-authentication-driver default/bawaan. Mohon diingat ketika membangun skema model ini untuk memastikan kolom password panjang minimum 60 karacter.

Jika aplikasi tidak menggunakan Eloquent, Anda bisa menggunakan database authentication-driver yg menggunakan Laravel-query-builder.

Note: Sebelum memulai, pastikan bahwa tabel users (atau semisalnya) memiliki kolom string remember_token. Kolom ini akan digunakan untuk menyimpan sebuah token pada fungsi “remember me” yg dikelola oleh aplikasi.

Menyimpan Password

Class Hash di Laravel menyediakan hash Bcrypt yg aman:

Membuat Hash Password Menggunakan Bcrypt

$password = Hash::make('secret');

Verifikasi Password Hash

if (Hash::check('secret', $hashedPassword))
{
 // The passwords match...
}

Cek Apakan Password Perlu Dibuat Hash Ulang

if (Hash::needsRehash($hashed))
{
 $hashed = Hash::make('secret');
}

Autentikasi User

Untuk memasukan/log-in user ke dalam aplikasi, Anda bisa menggunakan perintah Auth::attempt.

if (Auth::attempt(array('email' => $email, 'password' => $password)))
{
 return Redirect::intended('dashboard');
}

Perlu dicatat bahwa email bukan opsi wajib, diatas hanya contoh. Anda bisa menggunakan kolom apa saja sebagai “username” di database. Fungsi Redirect::intended akan mengarahkan/redirect user ke URL yg sebelumnya hendak diakses sebelum tertangkap oleh filter autentikasi. Sebuah URI alternatif diberikan pada perintah tsb sbg alternatif bila alamat halaman yg hendak dituju user tidak tersedia.

Ketika perintah attempt dipanggil,  event  auth.attempt akan terjadi. Bila proses autentikasi berhasil dan user telah masuk, event auth.login akan terjadi.

Untuk memastikan apakah user telah masuk ke aplikasi, Anda bisa menggunakan perintah check:

Memastikan Apakah User Sudah Di-Autentikasi

if (Auth::check())
{
 // The user is logged in...
}

Autentikasi User Dan “Mengingat” Mereka

Jika ingin menyediakan fungsi “remember me” pada aplikasi, Anda bisa memberikan true sbg argumen kedua pada perintah attempt, yg akan menyimpan autentikasi-user tanpa batas waktu atau hingga mereka logout. Tentu saja, tabel users harus memiliki kolom string remember_token, yg akan digunakan untuk menyimpan token “remember me”.

if (Auth::attempt(array('email' => $email, 'password' => $password), true))
{
 // The user is being remembered...
}

Note: Jika perintah attempt memberikan return true, berarti user telah masuk ke aplikasi.

Memastikan Apakah User Diautentikasi Via “Remember Me”

Jika Anda “mengingat” login user, Anda bisa menggunakan perintah viaRemember untuk memastikan apakah user di-autentikasi melalui cookie “remember me”:

if (Auth::viaRemember())
{
 //
}

Anda juga bisa menambahkan kondisi tertentu pada query autentikasi:

Autentikasi User Dgn Kondisi Tertentu

if (Auth::attempt(array('email' => $email, 'password' => $password, 'active' => 1)))
{
 // The user is active, not suspended, and exists.
}

Note: Untuk perlindungan tambahan terhadap session-fixation, ID-Session pengguna akan otomatis diperbarui setelah melakukan autentikasi.

Begitu user terautentikasi, Anda bisa mengakses model User / record:

Mengakses User Yg Telah Log-In

$email = Auth::user()->email;

Untuk memasukan user ke aplikasi (log-In) dgn ID mereka, gunakan perintah loginUsingId:

Auth::loginUsingId(1);

Perintah validate memungkinkan untuk memvalidasi kredensial/password tanpa benar-benar log-in, tanpa masuk ke sistem:

Validasi User Kredensial/Password Tanpa Login

if (Auth::validate($credentials))
{
 //
}

Anda bisa menggunakan perintah once untuk log-in user hanya untuk sekali proses request.Takada session atau cookie yg akan digunakan.

Log-In User Untuk Sekali Request

if (Auth::once($credentials))
{
 //
}

Log-Out User Dari Aplikasi

Auth::logout();

Log-In User Manual

Jika perlu log-in user ke aplikasi, Anda bisa dgn mudah memanggil perintah login:

$user = User::find(1);

Auth::login($user);

Cara ini sama dgn log-in user menggunakan perintah attempt.

Mengamankan Route

Filter Route bisa digunakan untuk membatasi supaya user terautentikasi saja yg boleh mengakses route tertentu. Laravel menyediakan filter auth secara default, dan telah dibuat pada app/filters.php.

Mengamankan Sebuah Route

Route::get('profile', array('before' => 'auth', function()
{
 // Only authenticated users may enter...
}));

Pengamanan CSRF

Laravel menyediakan perintah yg sederhana untuk mengamankan aplikasi Anda dari cross-site request forgeries.

Memasukan Token CSRF Pada Form

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

Validasi Token CSRF Yg Dikirim (Submit)

Route::post('register', array('before' => 'csrf', function()
{
 return 'You gave a valid CSRF token!';
}));

Autentikasi Dasar HTTP

autentikasi dasar HTTP menyediakan cara cepat untuk autentikasi user aplikasi tanpa seting halaman “login” khusus. Untuk memulai, lampirkan filter auth.basic pada route:

Mengamankan Route Dengan HTTP Dasar

Route::get('profile', array('before' => 'auth.basic', function()
{
 // Only authenticated users may enter...
}));

Secara default, filter basic akan menggunakan kolom email pada kolom user untuk proses autentikasi. Jika Anda ingin menggunakan kolom lainnya, Anda bisa memberikan nama kolom sbg parameter pertama pada perintah basic pada file app/filters.php:

Route::filter('auth.basic', function()
{
 return Auth::basic('username');
});

Anda juga bisa menggunakan Autentikasi Dasar HTTP tanpa seting cookie identifikasi user pada session,  yg akan sangat berguna untuk autentikasi API. Untuk melakukannya, buat sebuah filter yg meberikan return perintah onceBasic:

Seting Filter Dasar HTTP Basic Tanpa Status Log-In

Route::filter('basic.once', function()
{
 return Auth::onceBasic();
});

Jika Anda menggunakan PHP FastCGI, autentikasi dasar HTTP tidak akan bekerja dgn baik secara default. Baris perintah berikut perlu ditambahkan ke file .htaccess:

RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Pengingat Password & Reset

Model & Tabel

Kebanyakan aplikasi web menyediakan cara pada user untuk me-reset password ketika lupa. Daripada implementasi ulang pada tiap aplikasi, Laravel menyediakan metode yg lebih nyaman untuk mengirimkan pengingat password dan melakukan password reset. Untuk memulai, verifikasi model User Anda merupakan implementasi dr kontrak Illuminate\Auth\Reminders\RemindableInterface. Tentu saja, model User yg termasuk pada framework telah mengimplementasikan antarmuka ini.

Implementasi Antarmuka RemindableInterface

class User extends Eloquent implements RemindableInterface {

 public function getReminderEmail()
 {
 return $this->email;
 }

}

Selanjutnya, sebuah tabel harus dibuat untuk menyimpan token-reset-password. Untuk generate migrasi tabel ini, eksekusi perintah Artisan auth:reminders-table:

Generate Migrasi Tabel Pengingat

php artisan auth:reminders-table

php artisan migrate

Controller Pengingat Password

Sekarang kita telah siap untuk generate controller pengingat password. Untuk generate otomatis tsb, gunakan perintah Artisan auth:reminders-controller yg akan membuat file RemindersController.php pada direktori app/controllers.

php artisan auth:reminders-controller

Controlller hasil generate memiliki perintah getRemind yg bertugas menampilkan pengingat password. Yg perlu Anda lakukan hanya membuat view  password.remind. View ini harus memiliki form standar yg memiliki isian kolom email. Form tsb dikirim dgn method POST ke RemindersController@postRemind.

Form sederhana pada view password.remind dicontohkan sbb:

<form action="{{ action('RemindersController@postRemind') }}" method="POST">
 <input type="email" name="email">
 <input type="submit" value="Send Reminder">
</form>

Sebagai pendukung untuk perintah getRemind, controller hasil generate tsb memiliki sebuah perintah postRemind yg bertugas mengirim email pengingat password kepada para user. Perintah ini menerima kolom email melalui variabel POST. Jika email pengingat password sukses terkirim kepada user, sebuah pesan status akan disimpankan ke session-flash. Jika gagal, sebuah pesan error yg akan disimpan.

Di dalam perintah controlller postRemind Anda bisa memodifikasi pesan yg dtampilkan ke user:

Password::remind(Input::only('email'), function($message)
{
 $message->subject('Password Reminder');
});

User Anda akan menerima email dgn link yg dialamatkan ke perintah controller getReset. Token pengingat password, yg akan akan digunakan sbg identifikasi pengingat password yg diminta, token tsb jg yg akan diberikan ke perintah pada controller. Perintah/action telah dikonfigurasi untuk memberikan return view password.reset yg harus Anda buat sendiri. Variabel token akan diberikan ke view tsb, dan Anda harus menempatkan token ini pada input form hidden dgn nama token, form reset password harus berisi kolom emailpassword, dan password_confirmation. Form harus di-POST-kan ke perintah RemindersController@postReset.

Contoh form sederhana pada view password.reset akan terlihat sbb:

<form action="{{ action('RemindersController@postReset') }}" method="POST">
 <input type="hidden" name="token" value="{{ $token }}">
 <input type="email" name="email">
 <input type="password" name="password">
 <input type="password" name="password_confirmation">
 <input type="submit" value="Reset Password">
</form>

Akhirnya, perintah postReset bertugas untuk benar-benar mengubah password pada media penyimpan data. Pada perintah/action controller ini, sebuah Closure diberikan ke perintah Password::reset mengubah atribut password pada User dan memanggil perintah save. Tentu saja, Closure ini menganggap model User menggunakan Eloquent model; akan tetapi, Anda bebas mengganti Closure ini sesuai kebutuhan agar kompatibel dgn sistem penyimpanan database.

Jika password berhasil di-reset, user akan mendapatkan arahan redirect ke halaman utama aplikasi. Pastinya, URL redirect ini dapat diatur. Jika reset gagal, user akan diarahkan kembali ke form reset dan sebuah pesan  error akan ditambahkan ke flash-session.

Validasi Password

Secara default, perintah Password::reset akan memverifikasi apakah input password sesuai dan minimal 6 karakter. Anda bisa mengatur/kostumisasi aturan ini menggunakan perintah Password::validator, yg menerima sebuah Closure. pada Closure ini, Anda bisa melakukan berbagai validasi thd password sesuai yg Anda inginkan. Ingat bahwa Anda tak perlu memverifikasi input konfirmasi password, karena otomatis dilakukan oleh framework.

Password::validator(function($credentials)
{
 return strlen($credentials['password']) >= 6;
});

Note: Secara default, token reset password kadaluarsa setelah 1 jam. Anda bisa mengubah ini melalui opsi reminder.expire pada file app/config/auth.php.

Enkripsi

Laravel menyediakan fasilitas mumpuni dgn enkripsi AES-256 via ekstensi PHP mcrypt:

Meng-enkripsi Data

$encrypted = Crypt::encrypt('secret');

Note: Pastikan untuk seting sederet 32 karakter, acak, pada opsi key pada file app/config/app.php. Jika tidak, fitur pengamanan ini tidak akan berjalan.

Dekripsi Data

$decrypted = Crypt::decrypt($encryptedValue);

Anda jg bisa mengatur cipher dan mode yg digunakan oleh peng-enkripsi:

Setting Cipher & Mode

Crypt::setMode('ctr');

Crypt::setCipher($cipher);

Authentication Driver

Laravel menawarkan database dan authentication driver eloquent dalam 1 paket. Untuk informasi selengkapnya tentang menambahkan authentication driver, lihatlah Dokumentasi Ekstensi Autentikasi.