Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 查询关系/关联时未执行Sequelize afterFind钩子_Node.js_Sequelize.js - Fatal编程技术网

Node.js 查询关系/关联时未执行Sequelize afterFind钩子

Node.js 查询关系/关联时未执行Sequelize afterFind钩子,node.js,sequelize.js,Node.js,Sequelize.js,我有两种型号User和Email电子邮件有一个来自用户的外键 数据库中电子邮件的值在保存到数据库之前被加密。当检索到电子邮件时,它会被解密。因此,电子邮件在数据库中永远不会是纯文本,但在API中使用时可以是纯文本。我正在使用以实现该功能 我指定的挂钩如下所示: hooks: { /** * The query will have plain text email, * The database has encrypted email. * Thus, enc

我有两种型号
User
Email
<代码>电子邮件有一个来自
用户的外键

数据库中电子邮件的值在保存到数据库之前被加密。当检索到电子邮件时,它会被解密。因此,电子邮件在数据库中永远不会是纯文本,但在API中使用时可以是纯文本。我正在使用以实现该功能

我指定的挂钩如下所示:

hooks: {
    /**
     * The query will have plain text email,
     * The database has encrypted email.
     * Thus, encrypt the query email (if any) BEFORE the query is fired
     **/
    beforeFind: query => {
        if (query && query.where && query.where.email) {
            const email = query.where.email;
            const AESHash = AES.encrypt(email, KEY, { iv: IV });
            const encrypted = AESHash.toString();
            query.where.email = encrypted;
            console.log(`[hook beforeFind] email "${email}" was changed to "${encrypted}"`);
        } else {
            console.log(`[hook beforeFind] skipped "${query ? JSON.stringify(query) : query}"`);
        }
    },
    /**
     * Once the result is retrieved, the emails (if any) would be encrypted.
     * But, the API expects plain text emails.
     * Thus, decrypt them BEFORE the query response is returned.
     */
    afterFind: query => {
        if (query && (query.dataValues || query.email)) {
            const email = query.dataValues || query.email;
            const decrypt = AES.decrypt(email, KEY, { iv: IV });
            const decrypted = decrypt.toString(enc.Utf8);
            if (query.dataValues) {
                query.dataValues.email = decrypted;
            } else {
                query.email = decrypted;
            }
            console.log(`[hook afterFind] email "${email}" was changed to "${decrypted}"`);
        } else {
            console.log(`[hook afterFind] skipped "${query ? JSON.stringify(query) : query}"`);
        }
    },
    /**
     * The API provides plain text email when creating an instance.
     * But emails in database have to be encrypted.
     * Thus, we need to encrypt the email BEFORE it gets saved in database
     */
    beforeCreate: model => {
        const email = model.dataValues.email;
        if (email.includes("@")) {
            const AESHash = AES.encrypt(email, KEY, { iv: IV });
            const encrypted = AESHash.toString();
            model.dataValues.email = encrypted;
            console.log(`[hook beforeCreate] email "${email}" was changed to "${encrypted}"`);
        } else {
            console.log(`[hook beforeCreate] skipped "${email}"`);
        }
    },
    /**
     * Once they are created, the create() response will have the encrypted email
     * As API uses plain text email, we will need to decrypt them.
     * Thus, Decrypt the email BEFORE the create() response is returned.
     */
    afterCreate: model => {
        const email = model.dataValues.email;
        if (!email.includes("@")) {
            const decrypt = AES.decrypt(email, KEY, { iv: IV });
            const decrypted = decrypt.toString(enc.Utf8);
            model.dataValues.email = decrypted;
            console.log(`[hook afterCreate] email "${email}" was changed to "${decrypted}"`);
        } else {
            console.log(`[hook afterCreate] skipped "${email}"`);
        }
    }
}
当我需要创建/查询
电子邮件
模型时,它们可以完美地工作。例如:

async function findEmail() {
    console.log("[function findEmail] Executing");
    const existingEmail = await Email.findOne({
        raw: true
    });
    console.log("[function findEmail] Result:", existingEmail);
}
async function findUser() {
    console.log("[function findUser] Executing");
    const existingUser = await User.findOne({
        include: [{ model: Email }],
        raw: true
    });
    console.log("[function findUser] Result:", existingUser);
}
和输出:

[function findEmail] Executing
[hook beforeFind] skipped "{"raw":true,"limit":1,"plain":true,"rejectOnEmpty":false,"hooks":true}"
[hook afterFind] email "ZxJlbVDJ9MNdCTreKUHPDW6SiNCTslSPCZygnfxE9n0=" was changed to "someone@example.com"
[function findEmail] Result: { id: 1, email: 'someone@example.com', user_id: 1 }
但是,当我查询
用户
模型并包括
电子邮件
模型时,它们不起作用。 例如:

async function findEmail() {
    console.log("[function findEmail] Executing");
    const existingEmail = await Email.findOne({
        raw: true
    });
    console.log("[function findEmail] Result:", existingEmail);
}
async function findUser() {
    console.log("[function findUser] Executing");
    const existingUser = await User.findOne({
        include: [{ model: Email }],
        raw: true
    });
    console.log("[function findUser] Result:", existingUser);
}
输出为:

[function findUser] Executing
[hook afterFind] skipped "null"
[hook beforeCreate] email "someone@example.com" was changed to "QuLr/hi7QaJ4vKmxneW0jqwyqQdwhQDQbp+qW1vGpPE="
[hook afterCreate] email "QuLr/hi7QaJ4vKmxneW0jqwyqQdwhQDQbp+qW1vGpPE=" was changed to "someone@example.com"
[function findUser] Result: { id: 1,
  name: 'John Doe',
  'Email.id': 1,
  'Email.email': 'QuLr/hi7QaJ4vKmxneW0jqwyqQdwhQDQbp+qW1vGpPE=',
  'Email.user_id': 1 }


我的问题是: 当查询其他模型时,在其中包含指定了钩子的模型时,为什么没有执行钩子

下面是我正在使用的完整代码:--on


这是sequelize中的一个已知问题,似乎没有任何计划来解决它。参见github问题

另一种方法是对模型属性使用getter和setter。然而,钩子的问题是它们不支持异步,因此没有承诺或回调


如果删除
raw:true
,是否有效?当你传递这些信息时,你会得到一个简单的结果数组,它不会将它们解析成不同的对象,也不会运行钩子。你也有很多错误,例如
const email=query.dataValues | | query.email
query.dataValues将始终未定义,因为您使用的是
raw:true
.1。否当我删除
raw:true
2时,它不起作用。我刚刚给出了一个例子来重现这个bug,在我实际使用这个bug的项目中,我使用
raw:true
和不使用它来查询模型。