当前位置: 首页 > 知识库问答 >
问题:

CakePHP 3表单字段的加/解密

苏磊
2023-03-14
core.php

Configure::write('Security.key','secretkey');
public $encryptedFields = array('patient_surname', 'patient_first_name');

public function beforeSave($options = array()) {
    foreach($this->encryptedFields as $fieldName){
        if(!empty($this->data[$this->alias][$fieldName])){
            $this->data[$this->alias][$fieldName] = Security::encrypt(
                $this->data[$this->alias][$fieldName],
                Configure::read('Security.key')
            );
        }
    }
    return true;
}

public function afterFind($results, $primary = false) {

    foreach ($results as $key => $val) {
        foreach($this->encryptedFields as $fieldName) {
            if (@is_array($results[$key][$this->alias])) {
                $results[$key][$this->alias][$fieldName] = Security::decrypt(
                    $results[$key][$this->alias][$fieldName],
                    Configure::read('Security.key')
                );
            }
        }
    }
    return $results;
}

共有1个答案

程墨竹
2023-03-14

解决这个问题的方法不止一种(请注意,下面的代码是未经测试的示例代码!在使用这些代码之前,您应该首先掌握新的基础知识)。

一种是自定义数据库类型,它将在将值绑定到数据库语句时加密,并在获取结果时解密。这是我更喜欢的选择。

下面是一个简单的示例,假设db列可以保存二进制数据。

<?php
namespace App\Database\Type;

use Cake\Database\Driver;
use Cake\Database\Type;
use Cake\Utility\Security;

class CryptedType extends Type
{
    public function toDatabase($value, Driver $driver)
    {
        return Security::encrypt($value, Security::getSalt());
    }

    public function toPHP($value, Driver $driver)
    {
        if ($value === null) {
            return null;
        }
        return Security::decrypt($value, Security::getSalt());
    }
}

注册自定义类型。

use Cake\Database\Type;
Type::map('crypted', 'App\Database\Type\CryptedType');

src/model/table/patientstable.php

最后,将加密列映射到注册类型,就这样,从现在开始,所有的事情都将自动处理。

// ...

use Cake\Database\Schema\Table as Schema;

class PatientsTable extends Table
{
    // ...
    
    protected function _initializeSchema(Schema $table)
    {
        $table->setColumnType('patient_surname', 'crypted');
        $table->setColumnType('patient_first_name', 'crypted');
        return $table;
    }

    // ...
}

下面是一个基本的示例,不需要进一步解释:

// ...

use Cake\Event\Event;
use Cake\ORM\Query;

class PatientsTable extends Table
{
    // ...
    
    public $encryptedFields = [
        'patient_surname',
        'patient_first_name'
    ];
    
    public function beforeSave(Event $event, Entity $entity, \ArrayObject $options)
    {
        foreach($this->encryptedFields as $fieldName) {
            if($entity->has($fieldName)) {
                $entity->set(
                    $fieldName,
                    Security::encrypt($entity->get($fieldName), Security::getSalt())
                );
            }
        }
        return true;
    }
    
    public function beforeFind(Event $event, Query $query, \ArrayObject $options, boolean $primary)
    {
        $query->formatResults(
            function ($results) {
                /* @var $results \Cake\Datasource\ResultSetInterface|\Cake\Collection\CollectionInterface */
                return $results->map(function ($row) {
                    /* @var $row array|\Cake\DataSource\EntityInterface */
                    
                    foreach($this->encryptedFields as $fieldName) {
                        if(isset($row[$fieldName])) {
                            $row[$fieldName] = Security::decrypt($row[$fieldName], Security::getSalt());
                        }
                    }
                    
                    return $row;
                });
            }
        );  
    }

    // ...
}

为了稍微分离这一点,您还可以将其移动到一个行为中,这样您就可以轻松地在多个模型中共享它。

另见

    null
 类似资料:
  • 我目前正在尝试解析我通过Chrome中的Postman插件发送的。然而,我得到的输出如下: 当我尝试调试时,会得到这个输出。当我尝试时,我得到一个空数组,所以我假设数据的格式不正确(只是一个字符串)。在我写我自己的算法之前,我想确定我没有用这个算法重新发明轮子。我做错什么了?或者,如果没有,是否存在一些CakePHP3函数来处理这个问题? 更新 我发现了代码中的错误,路由过程似乎以某种方式将pos

  • 现在数据被加密保存在数据库中...问题是我们仍然需要能够在MySQL上使用aes_decrypt来解密信息,而它返回null。 在CakePHP 3上,config/app.php: 然后使用: 我的MYSQL表: 注意:地址和注释只是为了测试。 然后,在CakePHP上,我创建了一个自定义数据库类型: 最后,将加密列映射到注册类型,就这样,从现在开始,所有的事情都将自动处理。

  • 可以像访问页面中的其他元素一样,使用原生DOM 方法访问表单元素。此外,每个表单都有elements 属性,该属性是表单中所有表单元素(字段)的集合。这个elements 集合是一个有序列表,其中包含着表单中的所有字段,例如<input>、<textarea>、<button>和<fieldset>。每个表单字段在elements 集合中的顺序,与它们出现在标记中的顺序相同,可以按照位置和name

  • 问题内容: 我的表格中有3个字段。我有一个提交按钮和一个“添加其他字段”按钮。我知道我可以使用表单类中的方法添加字段。 我是Python和Django的新手,并且陷入了一个初学者的问题;我的问题是: 当我单击“添加其他字段”按钮时,添加其他字段的过程是什么? 是否需要再次呈现表单? 我如何以及何时打电话,甚至必须打电话? 如何将参数传递给? 问题答案: 你的表单必须基于从POST传递给它的一些变量

  • 我正在尝试添加一个自定义字段到忍者表单(第3.3节)。到处都找不到完整的例子。 仔细查看代码,似乎过滤器'ninja_forms_register_fields'可以起到作用,但我无法让它在任何地方运行。

  • 问题内容: 有一个这样的表单字段,名为Planning,我需要将title属性添加到选择中,最后渲染如下: 如何实现? 问题答案: 你必须对该字段进行子类化,以采取任何方式指定你想要的标题以及显示新属性的小部件。 如果你有这样的事情(请注意:完全未经测试): …你应该能够做到这一点: