Mengenkripsi Atribut Model Eloquent Secara Otomatis
Di era aplikasi modern, keamanan data sensitif bukan lagi opsi—tapi keharusan. Salah satu trik sederhana namun powerful di Laravel adalah mengenkripsi field tertentu di database langsung lewat model Eloquent.
Bayangkan kita punya data profil user dengan kolom seperti gender
dan email
. Informasi ini, kalau bocor, bisa dipakai untuk profiling. Dengan sedikit sentuhan di model, kita bisa memastikan field tersebut selalu terenkripsi saat disimpan dan didekripsi otomatis saat diakses.
Contoh Implementasi
Berikut contoh kelas Profile
yang memanfaatkan Crypt
Laravel untuk mengenkripsi data:
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Crypt;
class Profile extends Model
{
/**
* Daftar atribut yang ingin dienkripsi.
*/
protected $encryptable = [
'gender',
'email',
];
/**
* Override magic getter.
*/
public function __get($key)
{
$value = parent::__get($key);
if (in_array($key, $this->encryptable) && !is_null($value)) {
try {
return Crypt::decryptString($value);
} catch (\Exception $e) {
// Kalau gagal didekripsi (misalnya data lama), kembalikan aslinya
return $value;
}
}
return $value;
}
/**
* Override magic setter.
*/
public function __set($key, $value)
{
if (in_array($key, $this->encryptable) && !is_null($value)) {
$value = Crypt::encryptString($value);
}
parent::__set($key, $value);
}
}
Bagaimana Cara Kerjanya?
-
Setter (
__set
) Saat Anda melakukan:$profile->email = 'user@example.com'; $profile->save();
Data
'user@example.com'
akan otomatis terenkripsi sebelum masuk database. -
Getter (
__get
) Saat diambil kembali:echo $profile->email;
Eloquent akan mendekripsi string tersebut, sehingga Anda tetap mendapat hasil plain text tanpa perlu manual decrypt.
-
Fallback Mode Kalau ada data lama yang belum terenkripsi,
try/catch
memastikan aplikasi tetap jalan tanpa error (akan dikembalikan dalam bentuk aslinya).
Kelebihan Pendekatan Ini
- Transparan → Developer tidak perlu repot memanggil
Crypt::encryptString()
atauCrypt::decryptString()
setiap kali. - Granular → Anda bisa pilih atribut mana saja yang perlu dienkripsi lewat
$encryptable
. - Backward Compatible → Data lama tanpa enkripsi tetap bisa dibaca.
Kapan Dipakai?
- Untuk data sensitif: email, nomor telepon, alamat rumah, informasi medis.
- Saat Anda ingin menambah lapisan keamanan ekstra di luar database-level encryption (misalnya MySQL TDE).
- Jika compliance (misalnya GDPR/ISO) mensyaratkan data tertentu harus dienkripsi.
Catatan Penting
-
Indexing & Searching Data terenkripsi tidak bisa dipakai untuk query langsung. Misalnya:
Profile::where('email', 'user@example.com')->first();
tidak akan berhasil, karena nilai di DB sudah terenkripsi. Untuk kebutuhan seperti ini, biasanya dibuat field hash tambahan.
-
Performa Enkripsi/dekripsi menambah overhead. Tidak masalah untuk field kecil, tapi jangan dipakai sembarangan di kolom yang sering dipakai untuk query massal.
-
Key Management Laravel menyimpan key di
.env
. Pastikan kunci ini aman dan punya prosedur rotasi yang jelas.
Kesimpulan
Dengan override getter dan setter di Eloquent, kita bisa membuat mekanisme enkripsi atribut otomatis yang clean, aman, dan praktis. Pendekatan ini cocok dipakai di aplikasi Laravel yang menyimpan data pribadi pengguna.
Keamanan memang tidak ada yang 100% sempurna, tapi langkah kecil seperti ini bisa jadi pembeda besar antara aplikasi yang rentan dan yang siap menghadapi ancaman.