Laravel 8 中 Payload 突然变为 NULL 时如何解决“Payload 无效”

问题描述 投票:0回答:3

尝试解密之前加密的密码时,我不断收到此错误:

The payload is invalid.

这是相关的堆栈跟踪:

#0 /home/improojf/public_html/vendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php(136): Illuminate\Encryption\Encrypter->getJsonPayload(NULL)
#1 /home/improojf/public_html/vendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php(164): Illuminate\Encryption\Encrypter->decrypt('eyJpdiI6InloT0U...', false)
#2 /home/improojf/public_html/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(261): Illuminate\Encryption\Encrypter->decryptString('eyJpdiI6InloT0U...')
#3 /home/improojf/public_html/app/Models/Server.php(29): Illuminate\Support\Facades\Facade::__callStatic('decryptString', Array)
#4 /home/improojf/public_html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(473): Server->getPasswordAttribute('eyJpdiI6InloT0U...')

这里最大的问题是加密器代码中的字符串随机变成

NULL
,这对我来说毫无意义。

另一个问题是,某些记录只是按照预期行事。

我用它做什么 这用于在数据库中存储 smtp/pop3 服务器的密码

我尝试了什么 这个问题通过不加密/解密密码就完美解决了,这搞乱了目的

它总是返回错误吗?不,事实上有一些记录表现正常

我的猜测是什么

php artisan cache:clear
可能是其他地方报道的一个选项,但我认为应该有另一个解决方案。到目前为止,我已经(未经测试)以下访问器,而之前我只有第二次 try/catch

public function getPasswordAttribute($value){
    try {
        return Crypt::decryptString($value);
    } catch (\Illuminate\Contracts\Encryption\DecryptException $e) {
        \Illuminate\Support\Facades\Artisan::call('cache:clear');
    }
    try {
        return Crypt::decryptString($value);
    } catch (\Illuminate\Contracts\Encryption\DecryptException $e) {
        if(app()->runningUnitTests())
            return $value;
        else
            throw $e;
       }
}
php laravel laravel-8 password-encryption
3个回答
9
投票

根据官方文档

Laravel 的加密服务提供了简单、方便的界面 用于使用 AES-256 通过 OpenSSL 加密和解密文本 AES-128 加密。

Laravel 的所有加密值均使用消息进行签名 身份验证代码 (MAC),因此它们的底层值无法被 修改或篡改过一次

在使用Laravel的加密器之前,您必须在config/app.php配置文件中设置密钥配置选项。

这意味着加密解密取决于

app key
值。如果生成新的应用程序密钥,则旧的加密值将无法与新的应用程序密钥一起使用

参考:https://laravel.com/docs/8.x/encryption

已更新

问题是由于数据类型为 varchar(191),加密值部分存储在数据库表中。

因此最好将数据类型

varchar(191)
更改为
longtext
text


0
投票

使用可空文本或长文本列


0
投票

就我而言,问题不是列类型,而是默认的 $attributes 值:

/**
 * The model's default values for attributes.
 *
 * @var array
 */

protected $attributes = array(
    'is_complete' => false,
    'responses' => [], //Problem was here
);

我通过删除

'responses' => [],
并定义一个访问器来解决:

public function getResponsesAttribute($value)
{
    return $value ? $value : collect();
}
© www.soinside.com 2019 - 2024. All rights reserved.