Я пытаюсь разработать небольшое приложение на Laravel 5.5, где я сделал abstract model, который расширяет Laravel eloquent model примерно так:
<?php
use Illuminate\Database\Eloquent\Model;
class AbstractModel extends Model
{
}
Теперь просто для общего соглашения я устанавливаю соединение с базой данных для этой модели:
<?php
use Illuminate\Database\Eloquent\Model;
class AbstractModel extends Model
{
/**
* Defining connection for database
*
* @var string
**/
protected $connection='mysql';
}
И я создал свою собственную модель, которая расширяет этот abstract class:
<?php
use Illuminate\Database\Eloquent\SoftDeletes;
class Posts extends AbstractModel
{
use SoftDeletes;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'unique_id', 'title', 'contents'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'id'
];
}
Определив это по умолчанию, мы узнаем, что он будет иметь соединение с базой данных mysql, аналогично fillable определены для массового назначения. Аналогичным образом я хочу создать одну переменную encrypt, которая будет encrypt и decrypt данными из базы данных, поэтому для этого я добавил accessor и mutator в свой encrypt variable внутри моей модели:
<?php
use Illuminate\Database\Eloquent\SoftDeletes;
class Posts extends AbstractModel
{
use SoftDeletes;
/**
* The attributes that will have encryption.
*
* @var array
*/
protected $encryption = ['unique_id', 'title', 'contents'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'unique_id', 'title', 'contents'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'id'
];
}
и настроил его обратно в моем abstract model:
<?php
use Illuminate\Database\Eloquent\Model;
class AbstractModel extends Model
{
/**
* Defining connection for database
*
* @var string
**/
protected $connection='mysql';
/**
* Defining encryption
*
* @var array
**/
protected $encryption = [];
public function setAttributes()
{
foreach ($this->encryption as $attributes)
{
$this->attributes[$attributes] = Crypt::encryptString($this->attributes[$attributes]);
}
}
public function getAttributes()
{
foreach ($this->encryption as $attributes)
{
$this->attributes[$attributes] = Crypt::decryptString($this->attributes[$attributes]);
}
}
}
Я думаю, что мой подход неправильный, поскольку для этих атрибутов не выполняется шифрование или дешифрование, я вижу, что данные, отправленные для создания строк, хранятся в базе данных без какого-либо шифрования и таким же образом извлекаются.
Более того, я хотел бы иметь случай использования, когда я шифрую эти поля, также их метод доступа к атрибутам или мутатор вызывается внутри их собственной модели, например:
<?php
use Illuminate\Database\Eloquent\SoftDeletes;
class Posts extends AbstractModel
{
use SoftDeletes;
/**
* The attributes that will have encryption.
*
* @var array
*/
protected $encryption = ['unique_id', 'title', 'contents'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'unique_id', 'title', 'contents'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'id'
];
public function setTitleAttributes($value)
{
return ucfirst($value);
}
public function getTitleAttributes($value)
{
return ucfirst($value)
}
}
Любые отзывы и комментарии приветствуются. Спасибо.






Во-первых, модель Eloquent имеет методы setAttribute() и getAttribute(), а не setAttributes() и getAttributes().
Во-вторых, для такой ситуации. Я бы предпочел Мероприятие Eloquent. Потому что методы setAttribute() или getAttribute() будут активированы только при динамическом доступе к атрибуту, например: $post->title.
Вы можете зашифровать атрибуты события saving. И расшифруйте его обратно с помощью события retrieved.
<?php
namespace App;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Database\Eloquent\Model;
abstract class AbstractModel extends Model
{
protected $connection = 'mysql';
protected $encryption = [];
protected static function boot()
{
parent::boot();
// When being retrieved, decrypt the attributes.
static::retrieved(function ($instance) {
foreach ($instance->encryption as $encryptedKey) {
$instance->attributes[$encryptedKey] = Crypt::decryptString($instance->attributes[$encryptedKey]);
}
});
// When saving (could be create or update) the modal, encrypt the attributes.
static::saving(function ($instance) {
foreach ($instance->encryption as $encryptedKey) {
$instance->attributes[$encryptedKey] = Crypt::encryptString($instance->attributes[$encryptedKey]);
}
});
// Once it's saved, decrypt it back so it's still readble.
static::saved(function ($instance) {
foreach ($instance->encryption as $encryptedKey) {
$instance->attributes[$encryptedKey] = Crypt::decryptString($instance->attributes[$encryptedKey]);
}
});
}
}
Когда вы решили использовать этот подход, не отменяйте оба метода setAttribute() и getAttribute(). Поскольку он, скорее всего, дважды зашифрует / расшифрует атрибуты.
Кроме того, это должны быть setTitleAttribute() и getTitleAttribute() - в единственном числе. А на setTitleAttribute() вы должны изменить атрибут title; не возвращает предполагаемое значение. Я также не вижу смысла использовать title с заглавной буквы, поскольку он все равно будет зашифрован.
<?php
namespace App;
class Post extends Model
{
protected $encryption = ['unique_id', 'title', 'contents'];
protected $fillable = ['unique_id', 'title', 'contents'];
// Expected to mutate the title attribute.
public function setTitleAttribute($value)
{
$this->attributes['title'] = ucfirst($value);
}
public function getTitleAttribute($value)
{
return ucfirst($value);
}
}
Надеюсь, это даст вам некоторые идеи.
Но когда я делаю $posts = App\Posts::find(3); Illuminate\Support\Facades\Crypt::decryptString($posts->name); в tinker, я получаю соответствующие результаты.
Я не могу точно сказать, что происходит. Необходимо видеть ваш код как в классах AbstractModel, так и в Post.
Оба они упомянуты выше в вопросе, я больше ничего не добавил, на самом деле, при тестировании я не использовал никаких аксессуаров и мутаторов внутри модели сообщения.
@NitishKumar Я решил попробовать это самостоятельно, используя Laravel 5.5 с базой данных sqlite. На моей машине все работает нормально. Проверьте код здесь: gist.github.com/risan/99d1cf2b71c0fa754d01ad45227b4697
Привет, спасибо, я сделал небольшую проверку своих миграций. Я установил длину по умолчанию для моей строки на 191, что вызывало проблему. Ваш код работает как шарм, когда я изменил значения по умолчанию, большое спасибо за помощь.
Привет, спасибо за обновление, я вижу, что все мои значения шифруются, но я получаю ошибку при получении данных
Illuminate\Contracts\Encryption\DecryptException with message 'The payload is invalid.'