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
Related
I am trying to authenticate the user using passport.I am trying to display message using flash.In the passport-config.js,I wrote the local strategy.When I run the code ,it give an error "req.flash is not a function " in passport-config.js file.This the first time I am using passport and flash.Please help me.Thanks in advance.
app.js
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const passport = require("passport");
const initializePassport=require('./passport-config')(passport);
const auth=require('./authenticate');
const bcrypt=require('bcrypt');
const session = require('express-session');
const flash = require('express-flash');
const Post=require("./Post");
const User=require('./User');
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
app.use(session({
secret:"secret",
resave:false, //this means session variables are not resaved if nothing is changed
saveUninitialized:false //this means we dont want to save empty value in session if there is no value
}))
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
// make all error and success flash messages available from all templates
res.locals.error = req.flash("error")
res.locals.success = req.flash("success")
next()
})
app.get("/login",function(req,res){
res.render('login');
})
app.post("/login",passport.authenticate('local',{
successRedirect:'/',
failureRedirect:'/login',
failureFlash:true
}))
passport-config.js
const LocalStrategy = require('passport-local').Strategy;
const mongoose=require('mongoose');
const bcrypt = require('bcrypt');
const User=require('./User');
function initialize(passport) {
const authenticateUser =(req,email, password, done) => {
User.findOne({email:email}).then(user=>{
if(!user){
// req.flash('error','This email is not registered');
return done(null,false,req.flash('error','This email is not registered'));
}
//Match password
bcrypt.compare(password,user.password,(err,isMatch)=>{
if(err){
// req.flash('error','Something went wrong!Please try again.');
throw err;
}
if(isMatch){
return done(null,user);
}
else{
req.flash('error','Password Incorrect');
return done(null,false, req.flash('error','Password Incorrect'));
}
});
}).catch(err=> console.log(err));
}
passport.use(new LocalStrategy({ usernameField: 'email' ,passReqToCallBack: true}, authenticateUser));
passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser((id, done) => {
User.findById(id,(err,user)=>{
done(err,user);
})
})
}
module.exports = initialize;
Try putting passport before the flash
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
passport.use(new LocalStrategy({ usernameField: 'email' , passReqToCallback : true}, authenticateUser));
I just had to add passReqToCallback : true.It works now.
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.
For some reason req.user is undefined, and after 4+ hours of trying to figure out why, I'm asking here. I even copy-pasted the server/index.js file of a friend's server, changed the auth strategy so it worked for mine, and I get the same issue.
Everything else is working. It redirects to auth0, comes back to the correct place, either creates a new user in the DB or finds the user. In passport.serializeUser it has all the data I passed along. But when I hit the '/auth/me' endpoint, req.user is undefined.
server/index.js
require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors')
const session = require("express-session");
const passport = require('passport');
const Auth0Strategy = require('passport-auth0');
const massive = require('massive');
const axios = require('axios');
const process = require("process");
const moment = require('moment');
const app = express();
//app.use(express.static(__dirname + './../build'));
app.use(bodyParser.json());
app.use(cors());
app.use(session({
secret: process.env.SECRET,
cookie: { maxAge: 60000 },
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
// Use the session middleware
massive(process.env.CONNECTION_STRING)
.then( (db) => {
console.log('Connected to Heroku')
app.set('db', db);
}).catch(err=>console.log(err))
passport.use(new Auth0Strategy({
domain: process.env.AUTH_DOMAIN,
clientID: process.env.AUTH_CLIENT_ID,
clientSecret: process.env.AUTH_CLIENT_SECRET,
callbackURL: process.env.AUTH_CALLBACK
}, (accessToken, refreshToken, extraParams, profile, done) => {
const db = app.get("db");
const userData = profile._json;
db.find_user([userData.identities[0].user_id]).then(user => {
if (user[0]) {
return done(null, user[0]);
} else {
db.create_user([
userData.given_name,
userData.family_name,
userData.email,
userData.identities[0].user_id
])
.then(user => {
return done(null, user);
});
}
});
}))
passport.serializeUser( (user, done) => {
//console.log('serializeuser', user)
done(null, user);
})
passport.deserializeUser( (id, done) => {
app.get("db").find_session_user([id])
.then(user => {
console.log(user);
done(null, user[0]);
});
})
app.get('/auth', passport.authenticate('auth0'));
app.get('/auth/callback', passport.authenticate('auth0', {
successRedirect: process.env.SUCCESS_REDIRECT
}))
app.get('/auth/me', (req, res) => {
console.log('auth/me endpoint hit')
console.log(req.user)
if(!req.user){
return res.status(401).send('No user logged in.');
}
return res.status(200).send(req.user);
})
app.listen(process.env.PORT, () => console.log(`Listening on port: ${process.env.PORT}`));
server/.env
CONNECTION_STRING=postgres:*****
SECRET=*******
AUTH_DOMAIN=****.auth0.com
AUTH_CLIENT_ID=***
AUTH_CLIENT_SECRET=***
AUTH_CALLBACK=http://localhost:8084/auth/callback
SUCCESS_REDIRECT=http://localhost:3000/
PORT=8084
Try moving the app.get('/auth', passport.authenticate('auth0')); line after the app.get('/auth/me', (req, res) => { block. app.get can do regex matches and goes with the first one that matches (http://expressjs.com/en/api.html#path-examples), and I think it's trying to run the /auth logic for the /auth/me path.
eI'm using:
framework: express
template engine :handlebars
authentification: passport / passport-local
So login process goes well, but in logout i have a problem:
//routes/users.js
//logout
router.get("/logout",(req,res)=>{
req.logout();
req.flash("success_msg","You are logged out");
console.log(req.user);
res.render("users/login");
});
//views/users/login.js
{{user}}
//app.js:
// Setting Global variables:
app.use(function(req,res,next){
res.locals.success_msg = req.flash("success_msg");
res.locals.error_msg = req.flash("error_msg");
res.locals.error = req.flash("error");
res.locals.user = req.user || null;
next();
});
So the probleme is that when i clic on logout, i'm redirected to login view but the user object still there(not null),and when I refresh the user is initialised to null,
So my problem why the user haven't been set to null before refirection ?
Full files codes :(app.js, routes/users.js, /config/passport.js)
* app.js
const express = require('express');
const methodOverride = require('method-override');
const mongoose = require('mongoose');
const exphbs = require('express-handlebars');
const bodyParser = require('body-parser');
const flash = require('connect-flash');
const session = require('express-session');
//const path = require("path");
const passport = require('passport');
const app=express();
// load routes :
const ideas = require("./routes/ideas");
const users = require("./routes/users");
//---------------Mongoose Connect-----------------------
//Map global promise = get rid of warning
mongoose.Promise = global.Promise;
//Connect to mongoose
mongoose.connect('mongodb://localhost/vidjot-db',{
useMongoClient: true
})
.then(function(){
console.log("MongoDB connected ...");
})
.catch(err => console.log(err));
//----------------Middlewares set in Use-----------------
// Static folder Set:
//app.use(express.static(path.join(__dirname,'public')));
app.use(express.static('public'));
// Session middleware :
app.use(session({
secret: 'mySecret',
resave: true,
saveUninitialized: true,
//cookie: { secure: true }
}));
// passport middleware :
app.use(passport.initialize());
app.use(passport.session());
// handlebars middleware :
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
// body parser middleware :
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
//methodOverride middleware:
app.use(methodOverride('_method'));
//Connect flash middleware:
app.use(flash());
//----------------My Own Middlewares-----------------
// Setting Global variables:
app.use(function(req,res,next){
res.locals.success_msg = req.flash("success_msg");
res.locals.error_msg = req.flash("error_msg");
res.locals.error = req.flash("error");
console.log("res.locals.user");
res.locals.user = req.user || null;
next();
});
/* app.use(function(req,res,next){
console.log("3ale rou7i");
console.log(Date.now());
req.att_x="karim";
next();
}) */
app.use(function(req,res,next){
console.log("hani ne5dem");
next();
});
//-----------------Routes-----------------------------
// Index Route:
app.get("/",(req,res) => {
res.render('index');
//console.log("get callback");
});
// about Route:
app.get("/about",(req,res)=>{
res.render("about",{title:"about1"});
});
// Use routes :
app.use("/ideas",ideas);
app.use("/users",users);
//--------------------------------------------------
//call local-strategy:
require("./config/passport")(passport);
//--------------------------------------------------
const port=5000;
app.listen(port,()=>{
console.log(`server started on port ${port}`);
});
* routes/users.js:
const express = require("express");
const mongoose = require("mongoose");
const bcrypt = require('bcryptjs');
const passport = require("passport");
const router = express.Router();
//--------------------------------------------------
// Load User Model:
require('../models/User');
const User = mongoose.model('Users');
//--------------------------------------------------
//login form
router.get("/login",(req,res)=>{
res.render("users/login");
});
//handle login form:
router.post('/login',
passport.authenticate('local', {
successRedirect: '/ideas',
failureRedirect: '/users/login',
failureFlash:true,
})
);
//logout
router.get("/logout",(req,res)=>{
req.logout();
req.flash("success_msg","You are logged out");
console.log("routes users",req.user);
res.render("users/login");
});
//register form
router.get("/register",(req,res)=>{
res.render("users/register");
});
// handle register form
router.post("/register",(req,res)=>{
let errors=[];
if(req.body.password != req.body.password2)
errors.push({"text":"password do not match"});
if(req.body.password.length < 4)
errors.push({"text":"password must be at least 8 characters"});
if(errors.length > 0)
res.render("users/register",{
errors:errors,
name:req.body.name,
email:req.body.email,
});
else{
User.findOne({email:req.body.email})
.then(user=>{
if(user){
req.flash("error_msg","email already registred");
res.render("/users/login");
}else{
const newUser = new User({
name:req.body.name,
email:req.body.email,
password:req.body.password,
date:req.body.date,
});
bcrypt.hash(newUser.password, 10, function(err, hash) {
if (err) throw err;
newUser.password=hash;
newUser
.save()
.then(user=>{
req.flash("success_msg","You are registered, You can connect Now");
res.redirect("/users/login");
}).catch(err=>{
console.log(err);
return;
});
});
}
})
}
});
//--------------------------------------------------
module.exports = router;
* config/passport.js :
const mongoose = require('mongoose');
const bcrypt = require("bcryptjs");
const LocalStrategy = require("passport-local").Strategy;
const passport = require("passport");
//-------------------------------------------------------
// Load User Model:
require('../models/User');
const User = mongoose.model('Users');
//-------------------------------------------------------
module.exports=function(passport){
passport.use(
new LocalStrategy({usernameField:'email'},function(email, password, done){
User.findOne({'email':email},function(err, user) {
if (err)
return done(err);
if (!user)
return done(null, false,{message:"You are not registred"});
if (!bcrypt.compareSync(password,user.password) ){
return done(null, false,{message:"Missing email or password !"});
}
return done(null, user);
});
}));
passport.serializeUser(function(user, done) {
console.log("SERIALIZE");
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log("DESERIALIZE");
User.findById(id, function(err, user) {
done(err, user);
});
});
}
You have middleware that set res.locals based on a logged in user for every request.
Your res.render() template uses that res.locals data when rendering the page.
When you call req.logout(), nobody clears the res.locals that were already set when the user was still logged in so res.locals.user is now inaccurate.
So, when res.render() gets called after the logout, res.locals are still set as if the user is logged in and thus the page renders that way.
A simple solution is to clear the locals when you logout so they don't wrongly indicate the user is still logged in:
//routes/users.js
//logout
router.get("/logout",(req,res)=>{
req.logout();
// clear user before rendering to indicate logged out
res.locals.user = null;
req.flash("success_msg","You are logged out");
console.log(req.user);
res.render("users/login");
});
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!