我正在使用pg
和node.js
。当用户使用auth0
小部件登录时,我将传递它返回的电子邮件并检查我的数据库以查看用户是否存在。如果用户不存在,我将它们插入数据库。我已经设法让这个工作与一个功能的黑客工作,但我会感谢一些帮助熨平它。
我面临的问题。
在检查数据库中的电子邮件时,它没有检查整个电子邮件地址。
var emailCheck = "SELECT id from public.user WHERE email=" + req.body.email;
req.body.email;
实际上是myemail@example.com
返回此错误,
column "myemail" does not exist
即使
myemail@example.com
确实存在。
无论发生什么错误,它都会继续插入电子邮件地址。如果它不存在则插入它。由于电子邮件中有唯一键,因此会抛出错误
重复键值违反了唯一约束“uk_user_email”
所以要解决这个问题,为什么在@符号后没有检查?我应该遵循什么逻辑来更改此函数以运行第一个查询,如果第一个查询找不到相关的电子邮件地址,则只运行第二个查询?
checkRegister: function(req, res) {
pool.connect(function(err, client, done) {
if (err) {
return console.error('error fetching client from pool', err);
} connection
var emailCheck = "SELECT id from public.user WHERE email=" + req.body.email;
var emailInsert = "insert into public.user (user_auth_level,email,account_locked,contract) " +
"values ('1','" + req.body.email + "','false','false')"
client.query(emailCheck, function(err, result) {
if (err) {
return console.error(err.message);
}
});
client.query(emailInsert, function(err, result) {
if (err) {
return console.error(err.message);
}
});
done();
});
pool.on('error', function(err, client) {
console.error('idle client error', err.message, err.stack)
});
}
答案 0 :(得分:3)
你需要用'来包装你的价值。使它成为字符串。没有字符串换行,它将在列之间进行比较。它应该是:
var yourQuery = "SELECT id from public.user WHERE email=" + req.body.email; // SELECT id from public.user WHERE email=myemail@example.com
var correntQuery = "SELECT id from public.user WHERE email='" + req.body.email + "'"; // SELECT id from public.user WHERE email='myemail@example.com'
Nodejs是同步的,您需要使用回调或承诺链接您的代码,如下所示:
checkRegister: function (req, res) {
pool.connect(function (err, client, done) {
if (err) {
console.error(err);
// should return response error like
return res.status(500).send();
}
var emailCheck = "SELECT id from public.user WHERE email=$1";
client.query(emailCheck, [req.body.email], function (err, result) {
if (err) {
console.error(err);
res.status(500).send();
return done(); // always close connection
}
if (result.rowCount > 0) {
let user = result.rows[0]
// return your user
return done(); // always close connection
} else {
var emailInsert = "insert into public.user (user_auth_level, email, account_locked, contract) " +
"values ('1', $1,'false','false') RETURNING *"
client.query(emailInsert, [req.body.email], function (err, result) {
if (err) {
console.error(err);
res.status(500).send();
return done(); // always close connection
} else {
if (result.rowCount > 0) {
let user = result.rows[0]
// return your user
return done(); // always close connection
}
}
});
}
})
})
pool.on('error', function (err, client) {
console.error('idle client error', err.message, err.stack)
});
}
答案 1 :(得分:1)
对于#1,问题是您没有引用输入值。由于(我假设)你可能不想担心引用/转义/等你自己的值,我会考虑使用parameterized queries。这将有助于保护您免受SQL注入(并且您当前的代码非常暴露于此)。
对于#2,它实际上并没有“抛出”该错误。该方法是异步的,并为回调提供错误。如果您想“按顺序”运行查询,则需要执行以下操作:
client.query(emailCheck, function(err, result) {
if (err) {
// should probably do `return done(err);` here
return console.error(err.message);
}
client.query(emailInsert, function(err, result) {
if (err) {
// same thing - probably need done(err) in here
return console.error(err.message);
}
return done();
});
});
注意调用是如何嵌入彼此“内部”的(特别是在回调内部)。