jack blank
jack blank

Reputation: 5195

req.user is undefined after sign up

I don't understand why req.user is undefined after signup but it is not at login. I thought I did pretty much the same thing for login.

After I do signup I get the user in the db, then do json the req.user and it returns null.

My end goal is to redirect to the / route after signup. In the / route I want to test to see if req.user is not null and give an appropriate message about if the user is authenticated or not .

const express = require("express");
const ejs = require("ejs")
const bodyParser = require("body-parser");
// const multer = require("multer");
const mongoose = require("mongoose");
const app = express();

const User = require("./database/models/user");


const port = process.env.port || 3000;

/**********Express session*********/
const expressSession = require("express-session");
/**********************************/
const passport = require("passport");
const localStrategy = require("passport-local").Strategy;

mongoose.connect("mongodb://localhost/passport-ajax");
//Make sure capital P for promise.
mongoose.Promise = global.Promise;



app.use(bodyParser.urlencoded({extended : true}));
app.use(bodyParser.json());
// app.use(multer({dest : "./uploads"}));

app.use(expressSession({
    secret : "longString",
    resave:false,
     saveUninitialized: false
}))



/********************Configure passport*************************/


passport.use("login",  new localStrategy({
    usernameField : "emailOrUsername",
    passwordField : "password",
    passReqToCallback : true
},
    function(req, username, password, done){
        console.log("HIT HERE");
        User.findOne({emailOrUsername: username})
            .then((user)=>{
                console.log("FINDING!!");
                if(!user){
                    console.log("My error: NO SUCH USER");
                    return done(null, false, "No such user");
                }
                if(password !== user.password){
                    console.log(`Password Doesnt Match`);
                    done(null, false , "Passwords dont match");
                }
                console.log("USER MATCHED!!");
                done(null, user)

            })
            .catch((err) => console.log(err));
    }
))

passport.use("signUp", new localStrategy({
    usernameField : "emailOrUsername",
    passwordField : "password",
    passReqToCallback : true
},
    function(req, username, password, done){
        // Removing from the DB first so there won't be multiple records while testing.
        User.remove({})
        .then(() =>{
            User.findOne({emailOrUsername : username})
                .then((user) => {
                    console.log("FINDING INSIDE SIGNUP");
                    if(user){
                        return done(null, false, "User "+ username + "allready exists. " );
                    }
                    var user = {
                        emailOrUsername : username,
                        password : password
                    };
                    new User(user).save()
                        //possible do done(err)
                        .then((newUser) =>{
                            if(!newUser) return done("Failed On Create User");
                            done(null, user)
                        })
                })
        })
        .catch((err) => {
            console.log(err);
        })
    }
))

function verifyAuth(req, res, next){
    if(!req.isAuthenticated()){
        return res.status(401).json({
            err : "Please login correctly. You received a 401 error.",
            sesstionId : req.session.id
        })
    }
    next();
}
app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser(function(user, done){
    done(null, user.id);
});

passport.deserializeUser(function(id, done){
    User.findById(id, function(err, user){
        done(err,user);
    })
})

/**************************************************************/


app.set("view engine", "ejs");

//file will be served like http://localhost:4000/style.css
app.use(express.static(__dirname + "/public"));

app.get("/", (req, res) => {
    console.log("req.user : ", req.user);
    console.log("session: ", req.session);
    const authenticated = req.user ? true : false;
    var query = req.query.message;
    res.render("index", {
        query,
        authenticated
    })
})

app.get("/signUp", (req, res) =>{
    res.render("signUp", {
    })
})

app.post("/signUp", (req, res, next) => {
    // console.log(req.body);


    passport.authenticate("signUp", function(err, user, info){
        if(err) console.log(err, " authenticate Signup error! ");
        if(!user) console.log("USER ERROR!");
        req.login(user, function(err) {
            if(err) return err;
            console.log("req.login called!")

            console.log("INFO, " , info)
        })
        // res.redirect("/");
        res.status(201).json({
            user : user,
            session : req.session,
            "req.user" :  req.user // This is null right now.
        });

    })(req, res, next)
}, function(err, req, res, next){
    console.log("req.isAuthenticated() >", req.isAuthenticated());
});
app.get("/login", (req,res) =>{
    res.render("loginForm");
});

app.post("/login", function(req, res, next)  {
    console.log("req.body : ", req.body)
    passport.authenticate("login", function(err, user, info){
        console.log("inside authenticate");
        if(err) console.log(err, " ", req.session.id);
        if(!user) console.log("No user : ", info);
        req.login(user, function(err) { // need this when using custom function
            if(err) console.log(err);
        });
        res.status(201).json({
            user : user,
            session : req.session,
            "req.user" :  req.user
        });
    })(req, res, next); // very import to call this self-executing function
}, function(err, req, res, next){
    //possible function here
});

app.get("/unProtected", (req, res) => {
    res.json({
        session : req.session,
        "req.user" : req.user
    })
})
app.get("/protected", verifyAuth, (req, res) =>{
    res.json({
        session : req.session,
        "req.user" : req.user
    });
});


app.listen(port, function(){
    console.log(`Listening on port ${port}`);
})

Upvotes: 0

Views: 3223

Answers (2)

rohan
rohan

Reputation: 81

I know its quite a late answer to your question. But right now when i was doing my project i came across the same problem. SO i would suggest you to have a local strategy of passport like this :

passport.use(new LocalStrategy(
function(username, password, done) {
    console.log(username);
    console.log(password);
    db.collection('user-details').findOne({user_name:username},(err,result)=>{
        if(err) {done(err)};
        if(result.length == 0){
            done(null,false);
        }else{
        const results = JSON.stringify(result);
        var hash1 = JSON.parse(results);
        var  hash = hash1.password;
        console.log( hash);
        bcrypt.compare(password,hash,function(err,response){
            if(response==true){
                return done(null,{user_id:hash1._id});
            }else{
                return done(null,false);
            }
        });
     }
   });
 }
 ));

and use this strategy in each post login and post register.In post register ; after storing the username and password to the database like this

 app.post('register.html',(req,res,next)=>{
 //store the username and password into the database
next();
});

Do remember to use next after the req,res object as it will transfer the control to the next middleware in the app; i.e. the middleware written just after this post method. And the middleware next to this will be passport's local strategy. Use it like this:

   app.post('/register.html',passport.authenticate('local',{
   successRedirect: '/website.html',
   failureRedirect: '/register.html'
   }));

Upvotes: 0

dNitro
dNitro

Reputation: 5345

req.login acts asynchronously, that's why you pass it a callback function. So you should move every response inside this callback this way you give it enough time to doing it's configuration:

req.login(user, function(err) {
  if (err) return err;
  console.log("req.login called!");
  console.log("INFO, ", info);
  return res.status(201).json({
      user: user,
      session: req.session,
      "req.user": req.user
  });
});

Also in passport.use("signUp"... you should call the callback with newUser:

var newUser = new User(user);
newUser.save(function(err) {
  if (err) throw err;
  done(null, newUser);
});

And also serialize your user with _id instead of id:

passpost.serializeUser(function(user, done) {
  done(null, user._id);
});

Upvotes: 1

Related Questions