Laravel: Шифрование данных моделей с помощью кастов
encrypted
. Давайте посмотрим, как это работает.Это выглядит примерно так:
Мы не хотим, чтобы номера паспортов пользователей хранились в нашей базе данных открытым текстом, поэтому шифрование является отличным способом их защиты. При этом можно зашифровать любые данные в ваших моделях, а не только пользовательские.
Настройка базы данных
Для базы данных не требуется ничего особенного. Вы должны убедиться, что столбец, который вы хотите зашифровать, является string
/text
(в зависимости от объёма данных), даже если исходное значение содержит только цифры, например, номера паспортов в нашем случае.
Настройка модели
В модель необходимо добавить свойство protected $casts
и столбец, который мы хотим зашифровать. В нашем случае это passport_number
:
// ...
protected $casts = [
'passport_number' => 'encrypted',
];
// ...
Вот и все! Теперь при сохранении номера паспорта в пользовательской модели он будет зашифрован, а при обращении к нему — расшифрован. Как это круто!
Важное Предупреждение: Защитите свой ключ приложения
Упомянутый выше алгоритм шифрования основан на значении APP_KEY
вашего приложения. В файле .env
должно быть примерно следующее:
APP_KEY=base64:QikAJAlo0evYLq2RYFxGv/PRrSIfJcNDj2qiFRp1oUs=
Говоря о шифровании, следует помнить о безопасности APP_KEY
. Если кто-то получит к нему доступ, он сможет расшифровать все ваши зашифрованные данные. Поэтому, пожалуйста, храните его в безопасности и никому не сообщайте.
Что произойдёт, если изменить ключ приложения
Ваш APP_KEY
генерируется заново каждый раз, когда вы выполняете php artisan key:generate
. Но что произойдёт с вашими зашифрованными данными, если вы измените APP_KEY
?
Зашифрованные данные будут потеряны!
Именно так. Если вы измените APP_KEY
, все ваши зашифрованные данные будут потеряны. Это связано с тем, что данный ключ используется для шифрования/дешифрования, и его изменение приводит к нарушению процесса дешифрования. Просто посмотрите на этот пример:
array: 10 ▼ // routes/web.php:23
0 => array:7 [▼
"id" => 1
"name" => "Prof. Flossie Rutherford IV"
"email" => "hulda.spencer@example.org"
"email_verified_at" => "2023-09-06T15:55:18.000000Z"
"passport_number" => "8864880769"
"created_at" => "2023-09-06T15:55:18.000000%"
"updated_at" => "2023-09-06T15:55:18.000000Z"
1 => array:7 [▼
"id" => 2
"name" => "Dylan Lueilwitz"
"email" => "qfritsch@example.com"
"email_verified_at" => "2023-09-06T15:55:18.000000Z"
"passport_number" => "3324108737"
"created_at" => "2023-09-06T15:55:18.000000Z"
"updated_at" => "2023-09-06T15:55:18.000000Z"
2 => array:7 [▼
"id" => 3
"name" => "Mary Harvey V"
"email" => "frederik.kreiger@example.net"
"email_verified_at" => "2023-09-06T15:55:18.000000Z"
"passport_number" => "6595462478"
"created_at" => "2023-09-06T15:55:18.000000Z"
"updated_at" => "2023-09-06T15:55:18.000000Z"
3 => array:7 [▼
"id" => 4
"name" => "Enid Monahan"
"email" => "dave.nitzsche@example.com"
"email_verified_at" => "2023-09-06T15:55:18.000000Z"
"passport_number" => "5141691749"
"created_at" => "2023-09-06T15:55:18.000000Z"
"updated_at" => "2023-09-06T15:55:18.000000%"
А если мы поменяем ключ:
Illuminate\Contracts\Encryption\DecryptException
The MAC is invalid.
Поэтому основная идея заключается в следующем: НЕ запускайте key:generate
на продакшен сервере.
Берегите APP_KEY
и не теряйте его. Неплохо хранить его резервную копию в надёжном месте.