如何使用Sequelize fn结合PostgreSQL crypt校验密码?
问题:Sequelize调用PostgreSQL crypt函数时参数被自动加单引号导致校验失败
已知用bcrypt模块可实现密码校验,出于好奇尝试通过Sequelize的fn方法结合PostgreSQL内置的crypt函数完成密码校验,编写了如下代码:
const user = await Users.findOne({ where: { username: myUsername, password: sequelize.fn('crypt', myPassword, 'password') } });
执行后生成的SQL语句如下:
SELECT "id", "username", "password" FROM "users" AS "Users" WHERE "Users"."username" = 'yosiazwan' AND "Users"."password" = crypt('testing', 'password');
可以看到crypt函数的第二个参数password被自动添加了单引号,在pgAdmin中执行该SQL会失败;手动去掉单引号后SQL可正常运行,需要解决如何让Sequelize生成的SQL中这个参数不带单引号的问题。
解决方案
问题出在直接传入字符串'password'时,Sequelize会把它当作普通字符串常量处理,自动添加单引号。要让它识别为数据库表的列名,需要使用sequelize.col('password')来包裹列名,这样Sequelize就会把它解析为字段引用而非字符串。
修改后的代码如下:
const user = await Users.findOne({ where: { username: myUsername, password: sequelize.fn('crypt', myPassword, sequelize.col('password')) } });
此时生成的SQL语句会是:
SELECT "id", "username", "password" FROM "users" AS "Users" WHERE "Users"."username" = 'yosiazwan' AND "Users"."password" = crypt('testing', "Users"."password");
这样crypt函数的第二个参数会正确引用Users表的password列,就能正常执行密码校验了。
内容的提问来源于stack exchange,提问作者Yosi Azwan
相关产品推荐
相关产品推荐

