mathiasgrimm/laravel-encrypted-attributes

加密且默认安全的Laravel模型属性

v1.0.0 2022-06-29 09:40 UTC

This package is auto-updated.

Last update: 2024-08-29 05:50:45 UTC


README

此包为任何Laravel模型添加安全默认的加密属性。

默认情况下,所有序列化(toArraytoJson)以及任何属性的默认获取器都将始终选择加密值而不是解密值。

要获取解密值,只需简单添加_decrypted后缀

echo $tenant->access_token_decrypted;

安装

composer require mathiasgrimm/laravel-encrypted-attributes ^1.0

背景

我在想如何改进现有的Eloquent转换encrypted 加密转换

Laravel文档

加密转换将使用Laravel内置的加密功能加密模型属性值。此外,encrypted:array、encrypted:collection、encrypted:object、AsEncryptedArrayObject和encrypted:collection转换与未加密的对应转换类似;然而,正如您所预料的,当存储在数据库中时,基础值是加密的。

Laravel的默认行为是在数据库中保持加密,其余为纯文本。我认为默认行为应该是始终加密,除非您明确要求解密。

在本阅读的其余部分,假设以下内容

  • local.encrypted-string是一个加密字符串,前面加上它被加密的环境。
  • plain-text-string只是一个未加密的纯文本字符串。

Laravel默认行为

下面的示例都将输出加密转换的属性为纯文本

logger($tenant, ['tenant' => $tenant]);
// Will output:
// [2022-06-23 12:10:32] local.DEBUG: {"access_token_github":"plain-text-string"} {"tenant":{"App\\Models\\Tenant":{"access_token_github":"plain-text-string"}}} 

print_r($tenant->toArray());
// Will print:
// Array
// (
//     [access_token_github] => plain-text-string
// )

echo  $tenant->toJson();
// Will print: {"access_token_github":"plain-text-string"}

echo $tenant->access_token_github;
// Will print: plain-text-string

配置

要使用加密属性,您只需要使用HasEncryptedAttributes特质,并将要加密的属性添加到模型的protected $encrypted = []属性中。

示例

// app/Models/Tenants.php
use MathiasGrimm\EncryptedAttributes\HasEncryptedAttributes;

class Tenants extends Model
{
    use HasEncryptedAttributes;
    
    protected $encrypted = [
        'access_token_github',
        'access_token_facebook',
    ];
}

// other.php
$tenant = Tenant::find(1);
// -------------------------------------------------------------------
// Example 1 - New Default Getter Behaviour
// -------------------------------------------------------------------
echo $tenant->access_token_github;
// Will print "local.encrypted-string".
// When using the accessor we always get the raw database value.
// Therefore, by default it's encrypted.
// -------------------------------------------------------------------
// Example 2 - (Same) Default Setter Behaviour
$tenant->access_token_github = 'plain-text-string';
// Will encrypt the value to "local.encrypted-string".
// -------------------------------------------------------------------
// Example 3 - Getting The Decrypted Value
// -------------------------------------------------------------------
echo $tenant->access_token_github_decrypted;
// Will print "plain-text-string".
// -------------------------------------------------------------------
// Example 4 - Setting a Raw Value 
// -------------------------------------------------------------------
$tenant->access_token_github_raw = 'local.encrypted-string';
// Will store the raw value

echo $tenant->access_token_github;
// Will print "local.encrypted-string".

echo $tenant->access_token_github_decrypted;
// Will print "plain-text-string".
// -------------------------------------------------------------------
// Example 5 - Update
// -------------------------------------------------------------------
$tenant->update([
    'access_token_github' => 'plain-text-string'
]);
// Will store/set the value "local.encrypted-string"
// -------------------------------------------------------------------
// Example 5.1 - Update With Raw
// -------------------------------------------------------------------
$tenant->update([
    'access_token_github_raw' => 'local.encrypted-string'
]);
// Will store/set the value of access_token_github to "local.encrypted-string"
// -------------------------------------------------------------------
// Example 6 - Query 
// -------------------------------------------------------------------
echo Tenant::where('access_token_github', 'plain-text-string')->count();
// Will print "0"
     
echo Tenant::where('access_token_github', 'local.encrypted-string')->count();
// Will print "1"
// -------------------------------------------------------------------
// Example 7 - toArray()
// -------------------------------------------------------------------
print_r($tenant->toArray());
// Will print:
// array [
//     'access_token_github' => 'local.encrypted-string'
// ]
// -------------------------------------------------------------------
// Example 8 - toJson()
// -------------------------------------------------------------------
print_r($tenant->toJson());
// Will print: "{"access_token_github": "local.encrypted-string"}"
// -------------------------------------------------------------------
// Example 9 - Collection ->keyBy('access_token_github')
// -------------------------------------------------------------------
$tenantsByAccessTokenGithub = collect([$tenant])->keyBy('access_token_github');

// works
$tenantsByAccessTokenGithub['local.encrypted-string'];

// undefined index
$tenantsByAccessTokenGithub['plain-text-string'];
// -------------------------------------------------------------------
// Example 10 - Collection ->keyBy('access_token_github_decrypted')
// -------------------------------------------------------------------
$tenantsByAccessTokenGithub = collect([$tenant])->keyBy('access_token_github_decrypted');

// undefined index
$tenantsByAccessTokenGithub['local.encrypted-string'];

// works
$tenantsByAccessTokenGithub['plain-text-string'];
// -------------------------------------------------------------------
// Example 11 - Getting Encrypted Attribute Environment
// -------------------------------------------------------------------
echo $tenant->access_token_github_environment;
// Will print: local

环境范围

当使用加密属性时,加密值的环境将被添加到加密字符串的前面。

示例

local.encrypted-string
testing.encrypted-string
staging.encrypted-string
production.encrypted-string
other.encrypted-string

通过这样做,我们可以根据前缀添加额外的检查。

这样我们就可以做类似以下的事情

// MyApiClient.php

$writeMethods = ['post', 'put', 'patch', 'delete'];

if (in_array($method, $writeMethods) && $this->access_token_github_environment != app()->environment()) {
    throw Exception("API is currently in read-only mode");
}   

原始想法