Node.js Passport Authentication - log is not defined error - javascript

I am working on user login page with node.js, passport, and postgres. I thought I got user authentication working. However, when I try to change pages I get this error and my server won't load anything. {"message":"log is not defined","error":{}}. I have been stuck on this error for hours now and can't figure out what is causing it. I am guessing that the session is somehow getting messed up but I could be wrong. I am hoping someone knows the answer. Here is my relevant code.
I am extremely new to web development and because of that I am sure it is probably something simple I am missing.
main-config.js
(function(appConfig) {
'use strict';
// *** main dependencies *** //
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const session = require('express-session');
const flash = require('connect-flash');
const morgan = require('morgan');
const nunjucks = require('nunjucks');
const passport = require('passport');
// *** view folders *** //
const viewFolders = [
path.join(__dirname, '..', 'views')
];
// *** load environment variables *** //
require('dotenv').config();
appConfig.init = function(app, express) {
// *** view engine *** //
nunjucks.configure(viewFolders, {
express: app,
autoescape: true
});
app.set('view engine', 'html');
// *** app middleware *** //
if (process.env.NODE_ENV !== 'test') {
app.use(morgan('dev'));
}
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
secret: 'anything',
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(express.static(path.join(__dirname, '..', '..', 'client')));
};
})(module.exports);
local.js
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
(username, password, done) => {
return db.one("SELECT * " +
"FROM Users " +
"WHERE Email=$1", [username])
.then((result)=> {
return done(null, result);
})
.catch((err) => {
return done(null, false, {message:'Wrong user name or password'});
});
}));
passport.js
module.exports = () => {
passport.serializeUser((user, done) => {
done(null, user.userid);
});
passport.deserializeUser((id, done)=>{
log.debug("deserialize ", id);
db.one("SELECT * FROM User " +
"WHERE user_id = $1", id)
.then((user)=>{
done(null, user);
})
.catch((err)=>{
done(new Error(`User with the id ${id} does not exist`));
})
});
};
auth.js
router.post('/login', authHelpers.loginRedirect, (req, res, next) => {
passport.authenticate('local', (err, user, info) => {
if (err) { handleResponse(res, 500, 'error'); }
if (!user) {
console.log("User Not Found");
handleResponse(res, 404, 'User not found');
}
if (user) {
req.logIn(user, function (err) {
if (err) { handleResponse(res, 500, 'error'); }
handleResponse(res, 200, 'success');
});
}
})(req, res, next);
});

It's a clear error message - log is not defined in the following line in passport
log.debug("deserialize ", id);
Define your log object with a logger and everything should be good. Or just remove it for now.

Related

req.isAuthenticated is not a function while using Express and passport

in the last few hours I setup a backend express server. It works just fine and now I tryed to implement an authorization with help of a tutorial.
The login works, but when I try to open /authrequired (so basically a future page which needs a logged in user to work) I get the error message: "TypeError: req.isAuthenticated is not a function"
Here is my index.js file:
const express = require('express');
const fs = require('fs');
const http = require('http');
const https = require('https');
const path = require('path');
const uuid = require('uuid').v4;
const session = require('express-session');
const FileStore = require('session-file-store')(session);
const bodyParser = require('body-parser');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const users = [
{id: '2f24vvg', email: 'test#test.com', password: 'password'}
]
// configure passport.js to use the local strategy
passport.use(new LocalStrategy(
{ usernameField: 'email' },
(email, password, done) => {
console.log('Inside local strategy callback')
// here is where you make a call to the database
// to find the user based on their username or email address
// for now, we'll just pretend we found that it was users[0]
const user = users[0]
if(email === user.email && password === user.password) {
console.log('Local strategy returned true')
return done(null, user)
}
}
));
// tell passport how to serialize the user
passport.serializeUser((user, done) => {
console.log('Inside serializeUser callback. User id is save to the session file store here')
done(null, user.id);
});
passport.deserializeUser((id, done) => {
console.log('Inside deserializeUser callback')
console.log(`The user id passport saved in the session file store is: ${id}`)
const user = users[0].id === id ? users[0] : false;
done(null, user);
});
const app = express();
app.enable('trust proxy')
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(session({
genid: (req) => {
console.log('Inside the session middleware')
console.log(req.sessionID)
return uuid() // use UUIDs for session IDs
},
store: new FileStore(),
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}))
app.use(passport.session());
app.post('/login', (req, res, next) => {
console.log('Inside POST /login callback')
passport.authenticate('local', (err, user, info) => {
console.log('Inside passport.authenticate() callback');
console.log(`req.session.passport: ${JSON.stringify(req.session.passport)}`)
console.log(`req.user: ${JSON.stringify(req.user)}`)
req.login(user, (err) => {
console.log('Inside req.login() callback')
console.log(`req.session.passport: ${JSON.stringify(req.session.passport)}`)
console.log(`req.user: ${JSON.stringify(req.user)}`)
return res.send('You were authenticated & logged in!\n');
})
})(req, res, next);
})
function isAuthenticated (req, res, next) {
if (req.session.user) next()
else next('route')
}
app.get('/authrequired', isAuthenticated, function (req, res) {
res.send('you hit the authentication endpoint\n')
})
app.use(express.static(path.resolve(__dirname, 'build')));
app.use(express.json());
// Redirect from http port to https
http.createServer(function (req, res) {
res.writeHead(301, { "Location": "https://" + req.headers['host'].replace(80,433) + req.url });
console.log("http request, will go to >> ");
console.log("https://" + req.headers['host'].replace(80,433) + req.url );
res.end();
}).listen(80, () => console.info('Listening on port', 80))
//Start https server
https.createServer({
key: fs.readFileSync('./ssl/privkey.key'),
cert: fs.readFileSync('./ssl/cert.cer'),
keepAlive: true
}, app).listen(443, () => console.info('Listening on port', 443));
Anyone got a clue? I saw similar questions on stackoverflow, but nothing worked for me.
There is no such function isAuthenticated. That's why you get the error.
Try replace it with if(req.session.user) {
Or by the example in express-session
// middleware to test if authenticated
function isAuthenticated (req, res, next) {
if (req.session.user) next()
else next('route')
}
app.get('/', isAuthenticated, function (req, res) {
// this is only called when there is an authentication user due to isAuthenticated
res.send('hello, ' + escapeHtml(req.session.user) + '!' +
' Logout')
})
EDIT: You also need to use passport session middleware, by adding
app.use(passport.session());
Make sure it is coming after the session init.

Passport Js Stuck After Calling Callback Url

I tried to implement twitter strategy using PassportJS for my ExpressJS application. However, it always stuck when calling the callback URL. Twitter actually called the callback route (I tried replacing passport.authenticate() with res.json()) but somehow when I put passport.authenticate() it got stuck. What could be the problem?
server
const express = require("express");
const cors = require("cors");
const session = require("express-session");
const csrf = require("csurf");
const compression = require("compression");
const helmet = require("helmet");
const MongoStore = require("connect-mongo");
const router = require("./routes/api.routes");
const passport = require("./middlewares/passport.middleware");
const app = express();
app.use(
cors({
origin: [
"https://api.twitter.com",
],
credentials: true,
})
);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
session({
secret: process.env.SECRET,
resave: true,
rolling: true,
saveUninitialized: true,
store: MongoStore.create({
mongoUrl: process.env.MONGODB_URI,
}),
cookie: {
// 1 hour
maxAge: 1000 * 60 * 60 * 1,
httpOnly: true,
},
})
);
app.use(passport.initialize());
app.use(passport.session());
app.use(csrf());
app.use(helmet());
app.use(compression());
app.use(router);
// error handler
app.use(function (err, req, res, next) {
if (err.code === "EBADCSRFTOKEN") {
// handle CSRF token errors here
return res.status(403).send({ message: "form tampered with" });
}
res.status(err.status || 500);
});
module.exports = app;
routes
// OAuth 1
router.route("/auth/twitter").get(passport.authenticate("twitter"));
router
.route("/auth/twitter/callback")
.get(passport.authenticate("twitter", { failureRedirect: "/error" }), (req, res) => {
// it never reached here
res.status(200).send({ msg: "success!" });
});
router.route("/error").get((req, res) => {
res.status(403).send({ msg: "authentication failed" });
});
passport config
passport.use(
new TwitterStrategy(
{
consumerKey: process.env.TWITTER_CONSUMER_KEY,
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
callbackURL: "http://127.0.0.1:5000/auth/twitter/callback",
passReqToCallback: true
},
async function (token, tokenSecret, profile, cb) {
try {
const user = await users.upsertUser(profile.id);
return cb(null, user);
} catch (err) {
return cb(err);
}
}
)
);
passport.serializeUser((user, cb) => {
cb(null, user.email);
});
passport.deserializeUser(async (username, cb) => {
try {
const user = await users.findUserBy("email", username);
// filter out data
cb(null, user);
} catch (err) {
cb(err);
}
});

Username entries all come out as 'null' in mongodb nodejs

I'm getting started in node.js and trying to create a user authentication system for my web application. I am watching a tutorial on YouTube and have followed every step through. When it comes to actually registering my user. the username entry in the collecting comes out as null. I'm not sure why this is happening, and I'm a rookie to javascript and node js. I am using passport, express and mongodb modules.
this is the video i am watching 'https://www.youtube.com/watch?v=m2ZzRZemc98'
If anyone knows how to fix my issue, please respond
Thanks
This is my main app.js
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");
const MongoClient = require("mongodb").MongoClient;
const passport = require("passport");
const Strategy = require("passport-local").Strategy;
const session = require("express-session");
const flash = require("connect-flash");
const authUtils = require("./utils/auth");
const hbs = require("hbs");
var indexRouter = require("./routes/index");
var usersRouter = require("./routes/users");
const authRouter = require("./routes/auth");
var app = express();
//Connet to MongoDB database
MongoClient.connect("mongodb://localhost", (err, client) => {
if (err) {
throw err;
}
const db = client.db("user-profiles");
const users = db.collection("users");
app.locals.users = users;
});
//Passport streategy
passport.use(
new Strategy((username, passport, done) => {
app.locals.users.findOne({ username }, (err, user) => {
if (err) {
return done(err);
}
if (!user) {
return done(null, false);
}
if (user.password != authUtils.hashPassword(password)) {
return done(null, false);
}
return done(null, user);
});
})
);
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser((id, done) => {
done(null, { id });
});
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "hbs");
hbs.registerPartials(path.join(__dirname, "views/partials"));
app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
app.use(
session({
secret: "session secret",
resave: false,
saveUninitialized: false
})
);
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use((req, res, next) => {
res.locals.loggedIn = req.isAuthenticated();
next();
});
app.use("/", indexRouter);
app.use("/users", usersRouter);
app.use("/auth", authRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
// render the error page
res.status(err.status || 500);
res.render("error");
});
module.exports = app;
This is my auth.js
const router = express.Router();
const authUtils = require("../utils/auth");
const passport = require("passport");
router.get("/login", (req, res, next) => {
const messages = req.flash();
res.render("login", { messages });
});
router.post(
"/login",
passport.authenticate("local", {
failureRedirect: "/auth/login",
failureFlash: "Wrong username or password"
}),
(req, res, next) => {
res.redirect("/users");
}
);
router.get("/register", (req, res, next) => {
const messages = req.flash();
res.render("register", { messages });
});
router.post("/register", (req, res, next) => {
const registrationParams = req.body;
const users = req.app.locals.users;
const payload = {
username: registrationParams.username,
password: authUtils.hashPassword(registrationParams.password)
};
users.insertOne(payload, err => {
if (err) {
req.flash("error", "User account already exists");
} else {
req.flash("success", "User account was registered succesfully");
}
res.redirect("/auth/register");
});
});
router.get("/logout", (req, res, next) => {
req.session.destroy();
res.redirect("/");
});
module.exports = router;
I fixed my error, it was a mistake i made in the handlebars file, i put the input name as none the class of form-control and then named it again. Obviously the js looked at the first name and not the second name

Cannot read property 'name' of undefined in nodejs using passport

I'm makking login system in node js whem I try to get user detail after logged in in log it says undefined
here is app.js
const express = require('express');
const session = require('express-session');
const mongoose = require('mongoose');
const passport = require('passport');
const bodyParser = require('body-parser');
const app = express();
//Passport Config
require('./config/passport')(passport);
//DB config
const db= require('./config/key').dbURI;
//Connect to mongodb
mongoose.connect(db,{ useNewUrlParser: true})
.then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
//ejs
app.set('view engine','ejs');
//Bodyparser
app.use(bodyParser.json());
app.use(express.urlencoded({ extended: false }));
//Express session
app.use(session({
secret: 'secret key',
resave: true,
saveUninitialized: true
}));
//passport middleware
app.use(passport.initialize());
app.use(passport.session());
//Routes
app.use('/', require('./routes/index'));
app.use('/users', require('./routes/users'));
app.listen(3000,console.log("Server started on 3000"));
here is my login system
router.post('/login', (req,res,next) => {
passport.authenticate('local',{
successRedirect: '/dashboard',
failureRedirect: '/users/login',
failureFlash: true
})(req,res,next);
});
here is my dashboard redirection code
route.get('/dashboard',ensureAuthenticated,(req,res) => {
console.log(req.admin);
res.render('dashboard', { admin : req.admin });
});
in this console.log(req.admin); it says undefined in log
here is passport config
const LocalStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const passport = require('passport');
//Load user model
const User = require('../models/admin');
module.exports=function(passport){
passport.use(
new LocalStrategy({ usernameField: 'email' }, (email,password,done) => {
//Check if user is available or not
User.findOne({ email: email })
.then(user => {
if(!user){
return done(null, false, console.log('That email is not registerd'));
}
//match password
bcrypt.compare(password, user.password, (err, isMatch) => {
if(err) throw err;
if(isMatch){
return done(null, user);
}else{
return done(null, false, console.log('Password Incorrect'));
}
});
})
.catch(err => console.log(err));
})
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
}
here is the code of auth.js
module.exports = {
ensureAuthenticated: function(req,res,next){
if(req.isAuthenticated()){
return next();
}
console.log('Please log in to view this resourse');
res.redirect('/users/login');
}
}
and in dashboard.ejs i'm using <%= admin.name %> and it gives error
Cannot read property 'name' of undefined
I don't know what's the matter here or what's i'm missing here
After successful authentication in passport.js, usedetails are assigned to "user" object in request through a passport middleware.
so you can access it using "req.user".
error
Include the new keyword while initializing the Strategy.
solution

"Router.use() requires a middleware function but got a undefined" error while using express and Passport.js

I am setting up my backend, but keep getting the "Router.use() requires a middleware function but got a undefined" error. Here is my code:
const express = require('express');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const passport = require('passport');
const LocalStrategy = require('passport-local');
const mongoose = require('mongoose');
var REQUIRED_ENV = "SECRET MONGODB_URI".split(" ");
REQUIRED_ENV.forEach(el => {
if (!process.env[el]) {
console.error("Missing required env var " + el);
process.exit(1);
}
});
mongoose.connect(process.env.MONGODB_URI);
const User = require('./backend/models').User;
const routes = require('./backend/routes/routes');
const auth = require('./backend/routes/auth');
const app = express();
app.use(logger('tiny'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: process.env.SECRET,
store: new MongoStore({ mongooseConnection: mongoose.connection })
}));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser((id, done) => {
User.findById(id).exec((err, user) => {
done(err, user);
});
});
passport.use(new LocalStrategy((username, password, done) => {
User.findOne({ username: username }, (err, user) => {
// if there's an error, finish trying to authenticate (auth failed)
if (err) {
console.error('Error fetching user in LocalStrategy', err);
return done(err);
}
// if no user present, auth failed
if (!user) {
// return done(null, false, { message: 'Incorrect username.' });
return done(null, false);
}
// if passwords do not match, auth failed
if (user.password !== password) {
// return done(null, false, { message: 'Incorrect password.' });
return done(null, false);
}
// username and password match! auth has has succeeded
return done(null, user);
});
}));
app.use('/', auth(passport));
app.use('/', routes);
const PORT = process.env.PORT || 3000;
app.listen(PORT, error => {
error
? console.error(error)
: console.info(`==> 🌎 Listening on port ${PORT}. Visit http://localhost:${PORT}/ in your browser.`);
});
The error points to the app.use(session({secret: process.env.SECRET... line but when I take that away it still produces the error but this time does not cite a specific line in the error message. I can show you my routes.js and auth.js files if you want but I don't think that is causing the problem.
Thanks so much!

Categories

Resources