加密/解密 Laravel 中的 DB 字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48785932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Encrypt/Decrypt DB fields in laravel
提问by Kalyana Kannan
I am encrypting/decrypting the DB field values in Laravel through accessors and mutators, which is working fine in normal eloquent transactions.
我正在通过访问器和修改器加密/解密 Laravel 中的 DB 字段值,这在正常的雄辩交易中工作正常。
class Person extends Model
{
use Notifiable;
protected $table = 'person';
public function getFirstNameAttribute($value)
{
return Crypt::decryptString($value);
}
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $guarded = array();
protected function user()
{
return $this->belongsTo('App\Models\User', 'useraccount_id', 'id');
}
}
But the encryption and decryption not working under the following conditions
但是加密和解密在以下条件下不起作用
- Eloquent relationships
- DB raw queries
- 雄辩的关系
- 数据库原始查询
Working
在职的
$person = Person::find($person_id);
$person->firstName;
Not Working
不工作
$user = User::find($user_id);
$user->person->firstName;
回答by iman
You would probably have the encryption at the database level, as if someone gets access to the database you don't want them to be able to read people's medical data in plain text.
您可能会在数据库级别进行加密,就好像有人可以访问数据库一样,您不希望他们能够以纯文本形式读取人们的医疗数据。
You could create a trait that encrypts and decrypts data on save and retrieval respectively:
您可以创建一个特征,分别在保存和检索时加密和解密数据:
namespace App\Traits;
use Illuminate\Support\Facades\Crypt;
trait Encryptable
{
/**
* If the attribute is in the encryptable array
* then decrypt it.
*
* @param $key
*
* @return $value
*/
public function getAttribute($key)
{
$value = parent::getAttribute($key);
if (in_array($key, $this->encryptable) && $value !== '') {
$value = decrypt($value);
}
return $value;
}
/**
* If the attribute is in the encryptable array
* then encrypt it.
*
* @param $key
* @param $value
*/
public function setAttribute($key, $value)
{
if (in_array($key, $this->encryptable)) {
$value = encrypt($value);
}
return parent::setAttribute($key, $value);
}
/**
* When need to make sure that we iterate through
* all the keys.
*
* @return array
*/
public function attributesToArray()
{
$attributes = parent::attributesToArray();
foreach ($this->encryptable as $key) {
if (isset($attributes[$key])) {
$attributes[$key] = decrypt($attributes[$key]);
}
}
return $attributes;
}
}
You can then just apply the trait to your models, and define a property called $encryptable that's an array of columns whose data should be encrypted:
然后您可以将特征应用于您的模型,并定义一个名为 $encryptable 的属性,它是一个列数组,其数据应该被加密:
class YourModelextends Model
{
use Encryptable;
protected $encryptable = [
'code',
'keys',
'allergies'
];
}
回答by Harsukh Makwana
You can do it with laravel's CryptFacades. please follow this example.
你可以用 laravel 的CryptFacades来做到这一点。请遵循这个例子。
use Illuminate\Support\Facades\Crypt;
$encrypted = Crypt::encryptString('Hello world.');
$decrypted = Crypt::decryptString($encrypted);
I implemented from this article link : https://hackthestuff.com/article/laravel6-encryption-and-decryption-model-data-using-crypt-class
我从这篇文章链接实现:https: //hackthestuff.com/article/laravel6-encryption-and-decryption-model-data-using-crypt-class
回答by Lennart
Based on Iman his answer i changed the trait so it works with the casts array from Laravel self.
根据 Iman 他的回答,我更改了特征,因此它可以与 Laravel 自身的 casts 数组一起使用。
<?php
namespace App\Library\Traits;
use Illuminate\Support\Facades\Crypt;
trait Encryptable
{
/**
* If the attribute is in the encryptable array
* then decrypt it.
*
* @param $key
*
* @return $value
*/
public function getAttribute($key)
{
$value = parent::getAttribute($key);
if (isset($this->casts[$key]) && $value !== '' && !is_null($value) && $this->casts[$key] == 'encrypt') {
$value = decrypt($value);
}
return $value;
}
/**
* If the attribute is in the encryptable array
* then encrypt it.
*
* @param $key
* @param $value
*/
public function setAttribute($key, $value)
{
if (isset($this->casts[$key]) && $value !== '' && !is_null($value) && $this->casts[$key] == 'encrypt') {
$value = encrypt($value);
}
return parent::setAttribute($key, $value);
}
/**
* When need to make sure that we iterate through
* all the keys.
*
* @return array
*/
public function attributesToArray()
{
$attributes = parent::attributesToArray();
foreach ($this->casts as $key => $value) {
if($value == 'encrypt') {
if (isset($attributes[$key]) && $attributes[$key] !== '' && !is_null($attributes[$key])) {
$attributes[$key] = decrypt($attributes[$key]);
}
}
}
return $attributes;
}
}