dialect/laravel-gdpr-compliance

符合GDPR的数据可移植性和匿名化

1.4.7 2020-01-06 12:31 UTC

README

StyleCI

轻松实现GDPR合规的数据处理

此包帮助您符合GDPR要求;

7 条:同意的条件
17 条:被遗忘权
20 条:数据可移植权

目录

依赖项

  • PHP >= 7.0.0
  • Laravel >= 5.5

安装

首先,通过Composer包管理器安装此包

$ composer require dialect/laravel-gdpr-compliance

安装包后,您应该发布配置文件

$ php artisan vendor:publish --provider="Dialect\Gdpr\GdprServiceProvider" --tag=gdpr-config

配置

GDPR同意

此包包括一种让用户签署GDPR协议的方式。这将把用户重定向到指定路由上的协议,直到用户同意新条款。

要添加协议功能

  1. 发布中间件
    php artisan vendor:publish --provider="Dialect\Gdpr\GdprServiceProvider"
  2. 'gdpr.terms' => \App\Http\Middleware\RedirectIfUnansweredTerms::class
    添加到 app/Http/Kernel 中的 $routeMiddleware 中间件组中,如下所示
        protected $routeMiddleware = [
            'gdpr.terms' => \App\Http\Middleware\RedirectIfUnansweredTerms::class,
        ];
  3. 将中间件添加到您要检查的路由中(通常是使用认证的路由)
        Route::group(['middleware' => ['auth', 'gdpr.terms']], function () {
           Route::get('/', 'HomeController@index');
        });
  4. 将字段添加到 $fillable 中的用户模型
        protected $fillable = [
            'last_activity',
            'accepted_gdpr',
            'isAnonymized'
        ];
  5. 将协议文本修改为您的特定需求,在 resources/views/gdpr/message.blade.php

可移植性

Portable 特性添加到您想要可移植的模型中

namespace App;

use Dialect\Gdpr\Portable;

class User extends Model
{
    use Portable;
}

匿名化

Anonymizable 特性添加到您想要匿名化的模型中

namespace App;

use Dialect\Gdpr\Anonymizable;

class User extends Model
{
    use Anonymizable;
}

自动匿名化不活跃用户

此包添加了一个计划任务,旨在在用户不活跃一段时间后自动匿名化 User 模型。要指定时间,请编辑已发布配置中的 ttl 设置。
要激活此功能

  1. 将命令添加到 app/Console/Kernel.php 中的调度函数中,如下所示

        protected function schedule(Schedule $schedule)
        {
            $schedule->command('gdpr:anonymizeInactiveUsers')->daily();
        }
  2. 将类添加到同一文件中的 $commands 数组中,如下所示

```php
    protected $commands = [
        \Dialect\Gdpr\Commands\AnonymizeInactiveUsers::class,
    ];
```

配置可匿名化数据

在模型上,通过添加要在模型上匿名化的字段来设置 gdprAnonymizableFields,您还可以在模型上设置类似属性的函数来提供替换数据。
如果您在模型上有唯一约束,则应使用此功能。 如果没有提供值,将使用设置中的默认字符串。

/**
 * Using the default string from config.
 */
protected $gdprAnonymizableFields = [
    'name', 
    'email'
];
/**
 * Using replacement strings.
 */
protected $gdprAnonymizableFields = [
    'name' => 'Anonymized User', 
    'email' => 'anonymous@mail.com'
];
namespace App;

use Dialect\Gdpr\Anonymizable;

class User extends Model
{
    use Anonymizable;

    protected $gdprAnonymizableFields = [
        'email'
    ];
    
    /**
    * Using getAnonymized{column} to return anonymizable data
    */
    public function getAnonymizedEmail()
    {
        return random_bytes(10);
    }
}

递归匿名化

如果模型有相关模型,并且需要同时匿名化这些字段,请将相关模型添加到 $gdprWith。在相关模型上添加 Anonymizable 特性,并指定字段,如下所示 $gdprAnonymizableFields

class Order extends Model
{
    use Anonymizable;

	protected $guarded = [];
	protected $table = 'orders';
	protected $gdprWith = ['product'];
    protected $gdprAnonymizableFields = ['buyer' => 'Anonymized Buyer'];
    
	public function product()
	{
		return $this->belongsTo(Product::class);
	}
	public function customer()
	{
		return $this->belongsTo(Customer::class);
	}
}
class Customer extends Model
{
    use Anonymizable;
	protected $guarded = [];
	protected $table = 'customers';
	protected $gdprWith = ['orders'];

	protected $gdprAnonymizableFields = ['name' => 'Anonymized User'];

	public function orders()
	{
		return $this->hasMany(Order::class);
	}
}

调用 $customer->anonymize(); 也会更改相关订单上的 buyer 字段。

配置可移植数据

默认情况下,整个 toArray 形式的 App\User 模型都将可供下载。如果您想自定义可下载的数据,您可以在模型上重写 toPortableArray() 方法。

use Dialect\Gdpr\Portable;

class User extends Model
{
    use Portable;

    /**
     * Get the GDPR compliant data portability array for the model.
     *
     * @return array
     */
    public function toPortableArray()
    {
        $array = $this->toArray();

        // Customize array...

        return $array;
    }
}

延迟加载关系

您可能需要在可供下载的数据中包含一个关系。为此,将 $gdprWith 属性添加到您的 App\User 模型中。

use Dialect\Gdpr\Portable;

class User extends Model
{
    use Portable;

    /**
     * The relations to include in the downloadable data.
     *
     * @var array
     */
    protected $gdprWith = ['posts'];
}

隐藏属性

您可能希望限制包含在可下载数据中的属性,例如密码。为此,将 $gdprHidden 属性添加到您的 App\User 模型中。

use Dialect\Gdpr\Portable;

class User extends Model
{
    use Portable;

    /**
     * The attributes that should be hidden for the downloadable data.
     *
     * @var array
     */
    protected $gdprHidden = ['password'];
}

或者,您可以使用 $gdprVisible 属性来定义一个白名单,指定应包含在可供下载的数据中的属性。当模型转换时,所有其他属性将被隐藏。

use Dialect\Gdpr\Portable;

class User extends Moeld
{
    use Portable;

    /**
     * The attributes that should be visible in the downloadable data.
     *
     * @var array
     */
    protected $gdprVisible = ['name', 'email'];
}

使用方法

此包在 /gdpr/download 提供了一个端点。只有经过身份验证的用户才能访问这些路由。您的应用程序应向该端点发出一个 POST 调用,其中包含当前经过身份验证用户的密码。重新认证是为了防止信息泄露。

加密

在使用加密之前,您必须在 config/app.php 配置文件中设置一个 key 选项。如果此值未正确设置,所有加密值都将不安全。

您可以使用任何模型上的 EncryptsAttributes 特性动态加密/解密属性。该特性期望 $encrypted 属性填充属性键。

use Dialect\Gdpr\EncryptsAttributes;

class User extends Model
{
    use EncryptsAttributes;

    /**
     * The attributes that should be encrypted and decrypted on the fly.
     *
     * @var array
     */
    protected $encrypted = ['ssnumber'];
}

如果所有字段都加密了,模型可以以解密状态返回为数组或集合。

$decryptedArray = $this->decryptToArray();

$decryptedCollection = $this->customer->decryptToCollection();

匿名化

要匿名化模型,请在该模型上调用 anonymize()

class SomeController extends Controller
{
    public function anonymizeAGroupOfUsers() {
    	$users = User::where('last_activity', '<=', carbon::now()->submonths(config('gdpr.settings.ttl')))->get();
    	foreach ($users as $user) {
            $user->anonymize();
        }
    }
}

测试

安装后,您可以从 laravel-root 文件夹中运行此包的测试,命令为 phpunit vendor/Dialect/gdpr

安全漏洞

如果您在此项目中发现安全漏洞,请通过电子邮件发送给 Dialect,地址为 katrineholm@dialect.se。所有安全漏洞都将得到及时处理。

信用

sander3:原始包的作者,本包以此作为起点。

许可证

此包是开源软件,许可协议为 MIT 许可协议