javascript - 注册后 req.user 未定义

标签 javascript node.js express mongoose passport.js

我不明白为什么req.user在注册后是未定义但在登录时却不是。我认为我对登录做了几乎相同的事情。

注册后,我在数据库中获取用户,然后对 req.user 执行 json 操作,它返回 null。

我的最终目标是在注册后重定向到 / 路由。在 / 路由中,我想测试 req.user 是否不为空,并给出有关用户是否通过身份验证的适当消息。

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}`);
})

最佳答案

req.login 异步运行,这就是您向其传递回调函数的原因。因此,您应该移动此回调中的每个响应,这样您就可以给它足够的时间来进行配置:

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
  });
});

此外,在 passport.use("signUp"... 中,您应该使用 newUser 调用回调:

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

并且还使用 _id 而不是 id 序列化您的用户:

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

关于javascript - 注册后 req.user 未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41907430/

相关文章:

json - Javascript从node/express服务器读取gz文件

javascript - 标志窗口如何触发?

javascript - Axios API 响应 JSON 主体具有 "true/false"作为字符串类型而不是 bool 值

node.js - 无法使用 Hapi.js 回复设置 header

javascript - 处理快速异步中间件中的错误

node.js - 如何在 Node 和 Express 中从 API 调用中获取多个参数

javascript - 使用 mongoose find() 函数时,我收到 Promise <Pending>

javascript - Angular ng-show 在简单的示例脚本中没有按预期工作

json - RethinkDB 在根据 rfc6902 部分更新 json 文档时有用吗?

javascript - ZEIT 服务器无法读取 Multer 目标文件