I'm trying to add mySQL to passport.js to authenticate users in express.js, but can't seem to get await working. Server.js:
initializePassport(
passport,
function(email) {
pool.getConnection(function(err, connection) {
if (err) throw err;
console.log("Connected!");
pool.query("SELECT * FROM users WHERE email = ?", email, function (err, result) {
if (err) throw err;
return result[0];
connection.release();
});
});
},
)
The passport config
function initialize(passport, getUserByEmail) {
const authenticateUser = async (email, password, done) => {
try {
const user = await getUserByEmail(email);
console.log(user)
} catch (e) {
return done(e)
}
Right now it just prints undefined for user, and then prints Connected. I'm not sure why the await user isn't working.
Well if that's getUserByEmail()
, then it doesn't return a promise that is connected to when it's asynchronous operations are done, therefore, doing await getUserByEmail()
doesn't wait for anything.
await
ONLY does something useful if you are awaiting a promise that is connected to the operation you want to await for. Since you aren't even awaiting a promise, that await
does nothing useful. You would need to change getUserByEmail()
so that it returns a promise that is connected to the asynchronous operation you're trying to wait for.
For a function to return a promise that is connected to the asynchronous operations, you need to use promise-based asynchronous operations, not plain callback asynchronous operations, everywhere in that function. These are all database operations and all modern databases have a promise-based interface now so what you really want to do is to switch .getConnection()
, .query()
and .release()
to all use promise-based operations. This will also make it a lot simpler to implement proper error handling and proper communication back to the caller of errors.
I don't know mysql particularly well myself, but here's a general idea. The promise interface comes from the module mysql2/promise
:
const mysql = require('mysql2/promise');
const pool = mysql.createPool({...});
initializePassport(passport, async function(email) {
let connection;
try {
connection = await pool.getConnection();
console.log("Connected!");
let result = await pool.query("SELECT * FROM users WHERE email = ?", email);
return result[0];
} catch(e) {
// log the error and the rethrow so the caller gets it
console.log(e);
throw e;
} finally {
if (connection) {
connection.release();
}
}
});