Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@manjeshpv
Last active February 29, 2024 15:11
Show Gist options
  • Save manjeshpv/84446e6aa5b3689e8b84 to your computer and use it in GitHub Desktop.
Save manjeshpv/84446e6aa5b3689e8b84 to your computer and use it in GitHub Desktop.
Passport.js using MySQL for Authentication with Express
// config/passport.js
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : ''
});
connection.query('USE vidyawxx_build2');
// expose this function to our app using module.exports
module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
connection.query("select * from users where id = "+id,function(err,rows){
done(err, rows[0]);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
connection.query("select * from users where email = '"+email+"'",function(err,rows){
console.log(rows);
console.log("above row object");
if (err)
return done(err);
if (rows.length) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUserMysql = new Object();
newUserMysql.email = email;
newUserMysql.password = password; // use the generateHash function in our user model
var insertQuery = "INSERT INTO users ( email, password ) values ('" + email +"','"+ password +"')";
console.log(insertQuery);
connection.query(insertQuery,function(err,rows){
newUserMysql.id = rows.insertId;
return done(null, newUserMysql);
});
}
});
}));
// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
connection.query("SELECT * FROM `users` WHERE `email` = '" + email + "'",function(err,rows){
if (err)
return done(err);
if (!rows.length) {
return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
if (!( rows[0].password == password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, rows[0]);
});
}));
};
@L-Andy
Copy link

L-Andy commented Jan 3, 2020

thanks great mr

@daverave13
Copy link

perfect!! thank you

@imjvdn
Copy link

imjvdn commented May 18, 2020

@ekabelly you should avoid using crypto, you should use bcrypt instead.

how would you go about using bcrypt?

@cyberkuv
Copy link

cyberkuv commented Jun 2, 2020

@manjeshpv
Wow Thank you so much, you just helped me with my assignment!

@pageneck
Copy link

pageneck commented Sep 7, 2020

Thanks very much for sharing

@AliAzlanAziz
Copy link

AliAzlanAziz commented Dec 2, 2020

I am getting "Error: Failed to serialize user to session". I implemented above just changing very slightest code and using bcrypt. Plz help me here is the code https://stackoverflow.com/questions/65108451/error-failed-to-serialize-user-into-session

@jonathanfelicity
Copy link

Thanks for sharing, I found it useful.

@satya-tubunu
Copy link

bro thank you i have been looking for solution for 2 days

@DavidPerezContreras
Copy link

DavidPerezContreras commented Jun 29, 2023

It's a pretty nice code. I would suggest creating a local database connection for each method instead of declaring a global variable. Then, use connection.end() after you finished executing queries for that connection.

Here are some reasons why this approach is preferred:

Resource management: Opening and closing the database connection within each method ensures that the connection is only active when needed. This helps manage server resources more efficiently, especially in scenarios where multiple requests are being processed concurrently.

Connection isolation: Each method can have its own dedicated connection, which provides better isolation and prevents potential issues when multiple requests are accessing the database simultaneously. It avoids interference between queries executed by different Passport.js methods.

Error handling: With a dedicated connection in each method, error handling becomes more straightforward. If an error occurs during a query, it is easier to handle and propagate the error within that specific method, without affecting other parts of the application that may be using the database connection.

Flexibility: By creating connections within each method, you have the flexibility to configure the connection parameters specifically for that method's requirements. This allows you to customize options such as host, user, password, and database on a per-method basis if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment