'Export and Import Passport.JS Issues
I am using node js as the backend and react as the frontend. Within the backend, I would like to create a separate file that handles every passport.js module as shown below and imports passport.js into the user.js file so that the user input data can be passed to the passport file and returned when needed. The issue that I am running into is figuring out a way to import and export the passport.js file correctly. Any help would suffice, or even a "That's not possible" would too.
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mysql = require('mysql2');
const crypto = require('crypto');
const session = require('express-session');
const SqlDbStore = require('express-mysql-session')(session);
const db = require('./db');
app.use(session({
key: 'session_cookie_name',
secret: 'session_cookie_secret',
store: new SqlDbStore({
host: 'localhost',
port: 3306,
user: 'root',
password: 'xxxxxxxxxx',
database: 'xxxxxxxxxx',
}),
resave: false,
saveUninitialized: false,
cookie:{
maxAge:1000*60*60*24,
}
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.json());
app.use(express.static('public'));
app.use(express.static(__dirname + '/views'));
db.connect((err) => {
if (!err) {
console.log("BD Connected");
} else {
console.log("BD Conection Failed");
console.log(err.message);
}
});
const customFields={
firstNameField: 'usersFirstName',
lastNameField: 'usersLastName',
emailField: 'usersEmail',
passwordField:'usersPassword',
confirmPasswordField:'usersConfirmedPassword'
};
/*Passport JS*/
const verifyCallback=(email,password,done)=>{
connection.query('SELECT * FROM USER WHERE usersEmail= ?', [email], function(error, results, fields) {
if (error) {
console.log('query error: ' + error);
return done(error);
}
if(results.length==0) {
return done(null,false, {message: 'Account is not recognized.'});
}
const isValid=validPassword(password, results[0].EncryptHash, results[0].EncryptPassword);
user={id:results[0].ID, email:results[0].usersEmail, hash:results[0].EncryptHash, password:results[0].EncryptPassword};
if(isValid) {
return done(null,user);
} else {
return done(null,false, {message: 'Password is incorrect.'});
}
});
};
const strategy = new LocalStrategy(customFields, verifyCallback);
passport.use(strategy);
passport.serializeUser((user,done)=>{
console.log("Inside serialize");
done(null, user.id);
});
passport.deserializeUser(function(userId, done) {
console.log('deserializeUser');
connection.query('SELECT * FROM User WHERE ID = ? ', [userId], function(error, results) {
done(null, results[0]);
});
});
/*middleware*/
function validPassword(password, hash, salt){
const hashVerify=crypto.pbkdf2Sync(password, salt, 10000, 60, 'sha512').toString("hex");
return hash === hashVerify;
};
function genPassword(password) {
var salt=crypto.randomBytes(32).toString('hex');
var genhash=crypto.pbkdf2Sync(password, salt, 10000, 60, 'sha512').toString('hex');
return {salt:salt, hash:genhash}
};
function checkAuthentication(req,res,next){
if(req.isAuthenticated()){
//req.isAuthenticated() will return true if user is logged in
next();
} else {
res.redirect("/login");
}
};
User.JS
const express = require('express');
const router = express.Router();
const db = require('../config/db');
const passport = require('../config/passport');
const routes = require('')('passport');
router.post('/register', (req, res) => {
const firstName = req.body.firstName;
const lastName = req.body.lastName;
const email = req.body.email;
const password = req.body.password;
const saltHash = genPassword(password);
const salt = passport.saltHash.salt;
const hash = passport.saltHash.hash;
db.query('SELECT * FROM Users WHERE UsersEmail = ? ', [email], (err, results) => {
if (err){
console.log(err)
} else if (results.length > 0) {
res.json({ message: 'Email is already registered!' });
} else {
db.query('INSERT INTO Users (UsersFirstName, UsersLastName, UsersEmail, UsersPasswordHash, UsersPasswordSalt) VALUES (?, ?, ?, ?, ?)', [firstName, lastName, email, hash, salt], (err, results) => {
if (err){
console.log(err);
};
res.send(results);
});
}
})
});
router.post('/login', passport.authenticate('local'));
module.exports = {router, passport};
Please note that my main reason for wanting to go this root is to prevent the following code below from being accessible in the console.
app.use(session({
key: 'session_cookie_name',
secret: 'session_cookie_secret',
store: new SqlDbStore({
host: 'localhost',
port: 3306,
user: 'root',
password: 'xxxxxxxxxx',
database: 'xxxxxxxxxx',
}),
resave: false,
saveUninitialized: false,
cookie:{
maxAge:1000*60*60*24,
}
}));
Update: So I was able to make the following changes to get closer. However, I get an error message that says "Missing Credentials" for passport-local.
Changes to code: User.JS
const express = require('express');
const app = express();
const router = express.Router();
const db = require('../config/db');
const session = require('express-session');
const SqlDbStore = require('express-mysql-session')(session);
const passport = require('passport');
const bodyParser = require('body-parser');
const mysql = require('mysql2');
const crypto = require('crypto');
const LocalStrategy = require('passport-local').Strategy;
//----------------------------------------- BEGINNING OF PASSPORT MIDDLEWARE AND SETUP ---------------------------------------------------
app.use(session({
key: 'session_cookie_name',
secret: 'session_cookie_secret',
store: new SqlDbStore({
host: 'localhost',
port: 3306,
user: 'root',
password: 'xxxxxxxxxx',
database: 'xxxxxxxxxx',
}),
resave: false,
saveUninitialized: false,
cookie:{
maxAge:1000*60*60*24,
}
}));
app.use(passport.initialize());
app.use(passport.session());
require('../config/ppc.js')(passport);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.use(express.static(__dirname + '/index'));
/*passport middleware*/
function genPassword(password) {
var salt=crypto.randomBytes(32).toString('hex');
var genhash=crypto.pbkdf2Sync(password, salt, 10000, 60, 'sha512').toString('hex');
return {salt:salt, hash:genhash}
};
function checkAuthentication(req,res,next){
if(req.isAuthenticated()){
//req.isAuthenticated() will return true if user is logged in
next();
} else{
res.redirect("/login");
}
};
//----------------------------------------- END OF PASSPORT MIDDLEWARE AND SETUP ---------------------------------------------------
router.post('/register', (req, res) => {
const firstName = req.body.firstName;
const lastName = req.body.lastName;
const email = req.body.email;
const password = req.body.password;
const saltHash = genPassword(password);
const salt = saltHash.salt;
const hash = saltHash.hash;
db.query('SELECT * FROM Users WHERE UsersEmail = ? ', [email], (err, results) => {
if (err){
console.log(err)
} else if (results.length > 0) {
res.json({ message: 'Email is already registered!' });
} else {
db.query('INSERT INTO Users (UsersFirstName, UsersLastName, UsersEmail, UsersPasswordHash, UsersPasswordSalt) VALUES (?, ?, ?, ?, ?)', [firstName, lastName, email, hash, salt], (err, results) => {
if (err){
console.log(err);
};
res.send(results);
});
}
})
});
router.post('/login', function(req, res, next){
console.log(req.body);
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login'
}, function(err, user, info){
console.log(err, user, info);
if(err) {
res.render ('login ', {Title:' Login ', ErrorMessage: err. Message});
}
if(!user) {
res.render ('login ', {Title:' Login ', ErrorMessage: info. Message});
}
return req.logIn(user, function(err){
if(err) {
res.render ('login ', {Title:' Login ', ErrorMessage: err. Message});
} else {
return res.redirect('/project');
}
});
})(req, res, next);
});
module.exports = router;
ppc.js
const LocalStrategy = require('passport-local').Strategy;
const express = require('express');
const db = require('./db');
module.exports = function (passport) {
db.connect((err) => {
if (!err) {
console.log("BD Connected");
} else {
console.log("BD Conection Failed");
console.log(err.message);
}
});
const customFields={
firstNameField: 'firstName',
lastNameField: 'lastName',
emailField: 'email',
passwordField:'password',
confirmPasswordField:'passwordConfirmation'
};
/*Passport JS*/
const verifyCallback=(email,password,done)=>{
connection.query('SELECT * FROM USER WHERE usersEmail= ?', [email], function(error, results, fields) {
if (error) {
console.log('query error: ' + error);
return done(error);
}
if(results.length==0) {
return done(null,false, {message: 'Account is not recognized.'});
}
const isValid=validPassword(password, results[0].UsersPasswordHash, results[0].UsersPasswordSalt);
user={id:results[0].ID, email:results[0].usersEmail, hash:results[0].UsersPasswordHash, salt:results[0].UsersPasswordSalt};
if(isValid) {
return done(null,user);
} else{
return done(null,false, {message: 'Password is incorrect.'});
}
});
};
const strategy = new LocalStrategy(customFields, verifyCallback);
passport.use(strategy);
passport.serializeUser((user,done)=>{
console.log("Inside serialize");
done(null, user.id);
});
passport.deserializeUser(function(userId, done) {
console.log('deserializeUser');
connection.query('SELECT * FROM User WHERE ID = ? ', [userId], function(error, results) {
done(null, results[0]);
});
});
function validPassword(password, hash, salt){
const hashVerify=crypto.pbkdf2Sync(password, salt, 10000, 60, 'sha512').toString("hex");
return hash === hashVerify;
};
}
Code Returned:
BD Connected
{ email: '[email protected]', password: '1234' } null false { message: 'Missing credentials' }
Error: No default engine was specified
and no extension was provided at new View
Solution 1:[1]
So here's what I had to do to resolve my issues.
For login, I had to update the code to the code below.
router.post('/login', function(req, res, next){
// console.log(req.body);
passport.authenticate('local', function(err, user, info){
// console.log('Error: ' + err);
// console.log('User ID: ' + user.id + ' User Email: ' + user.email + ' User Salt: ' + user.salt + ' User Hash: ' + user.hash);
// console.log('Info: ' + info);
console.log(err, user, info);
if(err) {
res.json({message: err.message});
}
if(!user) {
res.json({message: info.message});
}
req.logIn(user, function(err){
if(err) {
res.json({message: err.message});
} else {
return res.redirect('/');
}
});
})(req, res, next)});
For app.use, I needed the following app.use... Note the "require" line as that is super important to connect to the separate passport file that you are trying to import.
app.use(passport.initialize());
app.use(passport.session());
require('../config/ppc.js')(passport);
app.use(app._router);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(__dirname + '/../client/src/App'));
Now, I can hit "serializeUser," but I cannot hit "deserializeUser."
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |