req.user 注册后未定义
Posted
技术标签:
【中文标题】req.user 注册后未定义【英文标题】:req.user is undefined after sign up 【发布时间】:2017-06-13 22:18:21 【问题描述】:我不明白为什么注册后req.user
是undefined
但登录时却没有。我以为我在登录时做了几乎相同的事情。
在我注册后,我在数据库中获取用户,然后对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`);
)
【问题讨论】:
passport.use("signUp",
是干什么用的?
你就是这样使用护照的吧?我相信第一个参数是策略的名称。我相信的函数称为verify
函数。这就是您使用护照制定策略的方式。
对不起,我的意思是;如果您已经定义了/login
,为什么还要创建一个单独的?
好问题。我看到很多例子都是这样做的。我试着不这样做,只是使用注册策略不存储数据,然后我添加了signup
,看看它是否能帮助我解决req.user
的问题。
【参考方案1】:
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);
);
【讨论】:
我之前尝试过类似的方法。我现在会仔细检查是否有帮助。 我把它放进去,现在浏览器挂了。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.status(201).json( user : user, session : req.session, "req.user" : req.user // This is null right now. ); )
return
回复。
抱歉没有帮助,我也没有看到 console.log("req.login called!");
被调用。
我相信没有newUser
是我的错误。感谢您的帮助,我真的很感激。我将在其他时间再次检查并关闭问题。【参考方案2】:
我知道它对您的问题的回答很晚。但是现在当我做我的项目时,我遇到了同样的问题。所以我建议你有一个像这样的本地护照策略:
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);
);
);
));
并在每个帖子登录和帖子注册中使用此策略。在帖子注册中;像这样将用户名和密码存储到数据库之后
app.post('register.html',(req,res,next)=>
//store the username and password into the database
next();
);
记得在 req,res 对象之后使用 next,因为它会将控制权转移到应用程序中的下一个中间件;即在这个 post 方法之后编写的中间件。而旁边的中间件将是passport的本地策略。 像这样使用它:
app.post('/register.html',passport.authenticate('local',
successRedirect: '/website.html',
failureRedirect: '/register.html'
));
【讨论】:
以上是关于req.user 注册后未定义的主要内容,如果未能解决你的问题,请参考以下文章
Passport + NodeJs + Express 得到“req.user”未定义
req.isAuthenticated 为 false 且 req.user 未定义。我该如何解决这个问题?
在获取用户时使用 Passport-jwt 时 req.user 未定义
Passport JWT req.user 在我的一条路线中未定义