使用Crypt在Laravel PHPUnit测试中

3
我正在使用phpunit和Laravel进行一些测试。我有很多加密的数据库数据。
在我的一个测试中,我填写一个表单,一旦完成,就会使用 Crypt::encrypt('来自字段的数据') 对数据进行加密。
以下是代码:
$this->visit('/requests/create')
             ->seePageIs('/requests/create')
             ->type('FirstNameTest1', 'first_name')
             ->press('Create Request')
             ->see('The request has been created.');

// Fails here
$this->seeInDatabase('requests', ['first_name' => Crypt::encrypt('FirstNameTest1')]);

我收到了以下错误信息:

无法在数据库表[requests]中找到符合属性[{"first_name":"eyJpdiI6InFWbGJmSU9rR0NHMjFnMjR4QVVyalE9PSIsInZhbHVlIjoiaDBMcGNxYzdsRlhjNDd3M2E5OGxQbUVkaHhzdEpIOERDcytwQytzZUN4MD0iLCJtYWMiOiJlN2U2MzczYTlhMDgyYTMxOWJmMGQyZDU0MzFiMmZiZjhkMDM1ZjA2YWFhZGVkYTZhMGRkNGMzNDY0ZTAzMjZmIn0="}]的行。

我手动检查过创建后是否存在该记录,但并未显示出来。我记得读到过关于在运行测试时数据不持久化的问题,所以这是有道理的...但你能想到任何其他原因导致测试无法找到该记录吗?

2个回答

10

Crypt::encrypt()功能无法创建可复制的哈希值。这就是为什么您无法找到记录的原因,因为存储在数据库中的哈希值将与您正在查找的第二个哈希值不同。

例如,以下是php artisan tinker会话的输出:

>>> Illuminate\Support\Facades\Crypt::encrypt('hello');
=> "eyJpdiI6IlU5bFFhV3JTWHozMklKbjFNc2VqVlE9PSIsInZhbHVlIjoieHZOK2ZSc0pNWlJWeUNYRktVNHc2dz09IiwibWFjIjoiOTI3YjY3MDI5OWJjMTU2M2RhMWFkYmNkOTJmMmE0OTU4MGE5MDNlNTk5NWZiOTgxNjA3Yjk1YTZiNTc1NjAwZCJ9"
>>> Illuminate\Support\Facades\Crypt::encrypt('hello');
=> "eyJpdiI6IjRHWDBvNkFQZmhJSUd0aFByZEFROGc9PSIsInZhbHVlIjoib00waTBpYThRZ3dkNTA5WWUxZWd0QT09IiwibWFjIjoiNzAwYzQ1NzliOTRiODg0M2Y3YTQ0YWIzNWY5NDcwNTJiMDJiYTgxZmJkM2U4MmQ2OWM2OTE3OGY4ZWVhNzgxMCJ9"

正如你所看到的,对于相同的文本,Crypt::encrypt() 函数连续两次运行会产生不同的哈希值。

你需要为测试找到一个不同的断言,比如从数据库中检索记录并检查 Crypt::decrypt($first_name) == 'FirstNameTest1' 是否成立。


1
你真是个巫师!谢谢。我有一种感觉,就是这样的东西;只是无法表达出来。感激不尽。 - Marcel Gruber
如果您需要快速准确地搜索加密信息,可以使用HMAC。 https://paragonie.com/white-paper/2015-secure-php-data-encryption#index-encrypted-information - Scott Arciszewski

0

我知道这是一个旧的线程,但我想提供另一种解决方案,允许使用assertDatabaseHas

$this->app->instance('encrypter', tap(Mockery::mock(), function ($mock) {
    $mock
        ->shouldReceive('encrypt')->once()
        ->with('111223333', true)
        ->andReturnArg(0);
}));

那怎么能解决这个操作问题呢? - jartaud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接