一尘不染

如何编写一个钩子来解密使用 Prisma ORM 查询的数据

javascript

Basic information firstFastify:使用框架构建的 API ,使用PrismaORM 处理Postgres数据库的 crud 操作。

The problem:在将其存储到数据库之前,我必须加密几个字段。字段是:用户的NameEmail。加密是通过crypto-js库实现的。在存储数据之前加密数据很容易。我的问题在于在查询中使用加密数据时,例如通过电子邮件选择用户。电子邮件已加密。您可以看到它不能用作 where 条件,因为每次我加密相同的值时,它都会产生不同的加密值。如果它mathers,加密类型是AES

您可以在下面找到负责登录端点的代码,如您所见,它使用 X 电子邮件搜索用户,如果找到用户,它会比较其密码以验证凭据。它适用于未加密的电子邮件,但是当我对存储的值应用加密时,不再登录。

fastify.post(
    "/login",
    {
      schema: {
        description: "This is an endpoint to handle user login",
        tags: ["user", "login"],
        body: {
          type: "object",
          additionalProperties: false,
          required: ["email", "password"],
          properties: {
            email: { type: "string" },
            password: { type: "string" },
          },
        },
        response: {
          200: {
            description: "Login successful",
            type: "object",
            properties: {
              token: { type: "string" },
            },
          },
          204: {
            description: "No user found",
            properties: {},
          },
        },
      },
    },
    async (request, reply) => {
      let credentials = {
        email: request.body.email,
      };

      const prisma = new PrismaClient();

      try {
        const user = await prisma.users.findFirst({
          where: {
            email: credentials.email,
          },
        });

        if (!user) {
          reply.code(204);
          return;
        }

        const match = await fastify.bcrypt.compare(
          credentials.password,
          user.password
        );

        if (!match) {
          reply.code(204);
          return;
        }

        const token = fastify.jwt.sign(
          { email: user.email, password: user.password },
          { expiresIn: "12h" }
        );

        reply.code(200);
        return { token };
      } finally {
        prisma.$disconnect();
      }
    }
  );
}

What am I trying to achieve:据我所知,我需要能够在 Prisma 的查询上实现一个挂钩来解密电子邮件,以便能够在 where 条件下将它们与提供的电子邮件进行比较,问题是,如何?我尝试使用 Prisma 的中间件,但要么我很笨,无法让它工作,要么是错误的方法。任何人都知道如何处理这个问题?


阅读 93

收藏
2022-07-27

共1个答案

一尘不染

2

我要做的第一件事是评估您需要加密的原因,并确定静态数据加密或类似的数据是否满足要求。假设由于某种原因它没有,那么我会尝试为hashed_email. 然后你使用 SHA-3 之类的东西对电子邮件进行加盐 + 哈希处理,然后你可以使用 hashed_email 列进行查询,一旦你有了行,就可以在需要时解密电子邮件。

否则,除了加载每个用户并检查每个用户以查看登录名是否匹配之外,我看不到其他方法,这显然无法扩展。

2022-07-27