去年,我们为 Laravel Forge 引入了一个简单但出人意料地有用的功能:向服务器添加备注的能力。
在检查此功能的采用情况时,我们注意到客户经常在该字段中存储敏感数据。我们并未设计备注来存储敏感信息,因此我们发现自己现在需要对现有的未加密数据进行加密,同时还要允许将新数据作为加密数据插入 - 同时,无论备注是否已加密,仪表板都需要能够正确显示备注。
我们的迁移过程如下
- 运行一个命令,对所有现有的未加密服务器备注进行加密。
- 更新我们的模型以转换
notes
字段,根据需要进行加密或解密。
为此,我们依靠 Laravel 的自定义转换 功能来处理此“有时加密”的数据。我们创建了一个新的转换 SometimesEncrypted
,它允许我们优雅地解密加密的备注,或简单地返回在迁移期间可能可用的明文版本
<?php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Crypt;
class SometimesEncrypted implements CastsAttributes
{
/**
* Cast the given value.
*
* @param array<string, mixed> $attributes
*/
public function get(Model $model, string $key, mixed $value, array $attributes): mixed
{
if ($value === null || $value === '') {
return $value;
}
try {
return Crypt::decryptString($value);
} catch (DecryptException $e) {
return $value;
}
}
/**
* Prepare the given value for storage.
*
* @param array<string, mixed> $attributes
*/
public function set(Model $model, string $key, mixed $value, array $attributes): mixed
{
return ($value === null || $value === '') ? null : Crypt::encryptString($value);
}
}
使用此转换意味着我们还可以分两部分发布此更改
- 转换备注字段,在保存新服务器备注时对其进行加密。
- 通过将明文服务器备注存储回模型并允许
SometimesEncrypted
转换发挥作用,来迁移明文服务器备注。
Laravel 的自定义转换允许我们为用户实现无缝过渡,在不中断用户体验或现有功能的情况下加密敏感数据。你发现使用 Laravel 的自定义转换的哪些有趣方法?