撰寫完權限管理之後,如果覺得自己的內容還不夠安全,可以嘗試利用 Laravel 的內建功能,對文章的內容進行加密與解密。
在之前的文章 [Day 25] 覺得自己的系統還不夠安全?用 laravel 快速的加解密! 裡面,我們著重的提到了 Laravel 的 Accessor 和 Mutator,來協助我們存取物件時,固定會執行加解密的動作
public function getContentAttribute($content)
{
return decrypt($content);
}
public function setContentAttribute($content)
{
$this->attributes['content'] = encrypt($content);
}
雖然這個寫法挺特殊,不過可能有些人會覺得這個做法很不直觀。必須要記得 Laravel 對 Accessor 和 Mutator 的特殊規則,才會知道這兩個函數在做什麼。
在 Laravel 9 時,這個做法已經改變了!變成一個更加直接的作法。
利用現在 PHP 可以宣告回傳型態,以及可以指定 named argument 的特性,當你要宣告 accessor 時,你只需要設定回傳的型別為 \Illuminate\Database\Eloquent\Casts\Attribute
,並且設置 get
參數:
/**
* decrypt content
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
protected function content(): Attribute
{
return Attribute::make(
get: fn ($value) => decrypt($value),
);
}
這樣一來,我們取出的資料,就會被 decrypt()
過了!
要設置 mutator 也一樣簡單,就是加上 set
參數即可
/**
* encrypt and decrypt content
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
protected function content(): Attribute
{
return Attribute::make(
get: fn ($value) => decrypt($value),
set: fn ($value) => encrypt($value),
);
}
是不是比起之前的語法,要更加容易得多?
另外,如果你覺得這樣的作法,說不定會導致效率問題。 Laravel 也提供了一個簡單的最佳化方式
/**
* encrypt and decrypt content
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
protected function content(): Attribute
{
return Attribute::make(
get: fn ($value) => decrypt($value),
set: fn ($value) => encrypt($value),
)->shouldCache();
}
這樣就可以將加解密計算的結果快取起來了!
今天有關 Accessor 和 Mutator 的新作法就分享到這裡,我們明天見!