我有可以用这种方式解密密码的代码:
use ProjectName'Models'Some;
Some::find(1)->pass;
它会自动解密在我的数据库中加密的通行证。但如果我对我的模型做不同的请求,例如:
Some::find(1);
它不起作用。请有人解释一下我该做什么?
这是完整的代码:
trait Encryptable
{
public function getAttribute($key)
{
$value = parent::getAttribute($key);
if (in_array($key, $this->encryptable)) {
return Crypt::decrypt($value);
}
return parent::getAttribute($key);
}
public function setAttribute($key, $value)
{
if (in_array($key, $this->encryptable)) {
parent::setAttribute($key, Crypt::encrypt($value));
return;
}
parent::setAttribute($key, $value);
}
}
这是更新的答案
为了获得预期的行为,可以重写Illuminate'Database'Eloquent'Model
的hydrate()
方法,以便在数据库检索后解密模型。
最初的方法是:
/**
* Create a collection of models from plain arrays.
*
* @param array $items
* @param string|null $connection
* @return 'Illuminate'Database'Eloquent'Collection
*/
public static function hydrate(array $items, $connection = null)
{
$instance = (new static)->setConnection($connection);
$items = array_map(function ($item) use ($instance)
{
return $instance->newFromBuilder($item);
}, $items);
return $instance->newCollection($items);
}
你可以覆盖它,添加你的解密内容如下:
/**
* Create a collection of models from plain arrays.
*
* @param array $items
* @param string|null $connection
* @return 'Illuminate'Database'Eloquent'Collection
*/
public static function hydrate(array $items, $connection = null)
{
$instance = (new static)->setConnection($connection);
$items = array_map(function ($item) use ($instance)
{
foreach ($instance->encryptable as $attribute) {
// Remember to do any aditional check here, like check if is_null
// and catch any exceptions also.
$item->$attribute = 'Crypt::decrypt($item->$attribute);
}
return $instance->newFromBuilder($item);
}, $items);
return $instance->newCollection($items);
}
在这里,我们解决了模型加载的解密部分。
要解决保存时加密问题,可以使用saving
事件加密属性,然后在saved
事件中将它们还原为未加密的值。
这样,在您的应用程序上,模型总是简单的,但在数据库上,它将被加密。