我的问题类似于one,但没有深入了解他的解决方案。
我正在使用Passport使用Instagram进行身份验证。成功验证后,用户将被定向到“/”。此时,请求具有用户对象(也就是它正在工作)。但是,一旦我重定向,req.user是未定义的。 :'(
奇怪的是,每个请求都会调用passport.deserializeUser。它成功获取了用户对象,但在中间件路上的某个地方,req.user未被设置(或未被设置)。
// on successful auth, goto "/"
app.get('/', function(req, res) {
// if the request has the user object, go to the user page
if (req.user) {
res.redirect("/user/" + req.user._id);
}
res.render("index");
}
app.get('/user/:uid', function(req, res) {
console.log(req.user) // undefined
}
答案 0 :(得分:46)
我的问题是在客户端使用fetch时没有指定发送cookie。它包括凭证后工作:'包括'请求中的字段。
fetch('/api/foo', {credentials: 'include'})
答案 1 :(得分:36)
您是否为应用设置了会话状态?你需要这样的东西......
app.use(session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
答案 2 :(得分:15)
我是Node的新手,但对我来说这是一个中间件问题。添加了bodyParser并重新排列以修复。
代码破碎:
app.use(express.cookieParser('secret'));
app.use(express.cookieSession());
app.use(express.session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
工作代码:
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
希望这有帮助
答案 3 :(得分:8)
以前我有这些代码(不起作用):
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser('abcdefg'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({
secret: 'abcdefg',
resave: true,
saveUninitialized: false,
cookie: { secure: true } // this line
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
然后我从会话初始化程序中删除cookie选项:
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser('abcdefg'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({
secret: 'abcdefg',
resave: true,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
现在可行。
答案 4 :(得分:4)
是的,启用像@Martin这样的会议。但是,如果您使用的是Express 4. *版本,则不会捆绑像会话这样的中间件,因此您需要单独安装它。
var express = require('express');
var cookieParser = require('cookie-parser')
var session = require('express-session')
var app = express()
app.use(cookieParser()) // required before session.
app.use(session({secret: 'keyboard cat'}))
有关详细信息,请查看express session documentation.
答案 5 :(得分:4)
我遇到同样的问题,因为只是复制&粘贴来自快速会话文档的代码,但没有完全阅读文档。
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
在文档中,它提到:
但是,它需要启用https的网站,即HTTPS 安全cookie所必需的。如果设置了安全,您可以访问您的 通过HTTP站点,不会设置cookie。
因此,如果您只有HTTP连接,请删除安全选项,以下代码应该有效:
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
//cookie: { secure: true } remove this line for HTTP connection
}))
答案 6 :(得分:3)
在路线中,请尝试添加:{session: true}
app.get('/auto-login', passport.authenticate('cross', {session: true}))
答案 7 :(得分:3)
我使用快递4时遇到了同样的问题,在尝试了几乎我能在网上找到的所有内容后,我终于通过添加“cookie-session'”来设法让它发挥作用。
var cookieSession = require('cookie-session');
app.use(cookieSession({
keys: ['key1', 'key2']
}));
答案 8 :(得分:1)
'req.user' 仅在passport.auth 中间件之后才为我设置为用户。我来到这个线程试图找出如何从其他请求(没有passport.auth中间件)访问用户名,如果其他人被困在这个问题上,那么试试
req._passport.session.user;
答案 9 :(得分:1)
要解决此错误,请检查以下内容:
正确的方法(猫鼬):
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser((_id, done) => {
User.findById( _id, (err, user) => {
if(err){
done(null, false, {error:err});
} else {
done(null, user);
}
});
});
检查您的 cookie-session 程序包是否已正确配置并且可以正常工作。检查您是否真的可以在客户端看到cookie。如果您使用的是 express-session ,请确保可以在内存或缓存(Redis)中看到session-id。
确保您的反向代理支持cookie和请求类型。不要忘记检查cookie /会话配置[secure
标志]
遇到此错误时,我正在使用 (user)
作为回调函数。然后,我用 (err, user)
进行了更正。现在没事了。干杯?
答案 10 :(得分:1)
当您在客户端使用http请求时,请记住附加凭据。 在Angular2中,您需要添加选项参数:{withCredentials:true}。在此之后,您将拥有相同的req.sessionID,直到您再次重置它。
this._http.get("endpoint/something", { withCredentials: true })
答案 11 :(得分:1)
一旦设置了快速会话,请确保您拥有护照序列化&反序列化,在生成req.user时的反序列化函数中。请参阅另一个stackoverflow问题中的解释here。
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
答案 12 :(得分:1)
我的是饼干& CORS。 我通过将以下代码添加到我的服务器来解决:
allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3000'); // your website
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
if ('OPTIONS' === req.method) {
res.send(200);
} else {
next();
}};
答案 13 :(得分:0)
有完全相同的问题。对我来说,解决方案是使用"客户端会话"而不是' express-session"。可能是糟糕的会话配置?
不工作代码:
var session = require('express-session');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(session({
secret: 'random string',
resave: true,
saveUninitialized: true,
cookie: { secure: true }
}));
工作代码:
var session = require('client-sessions');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(session({
cookieName: 'session',
secret: 'random string',
duration: 30 * 60 * 1000,
activeDuration: 5 * 60 * 1000,
}));
答案 14 :(得分:0)
我在req.isAuthenticated()和req.user中都遇到了相同的问题,这是我的解决方法
req.isAuthenticated() 通过在deserialize()内的findById()方法中用find()替换findOne()来解决,然后我可以保存经过身份验证的请求,否则将不返回任何内容。
req.user 通过调整顺序解决,应该先存储快速会话,然后初始化护照,然后将下一个会话存储在passport.session()中,然后在将会话保存在passport.session()中之后,我们可以访问req.user
app.use(session(...));
app.use(passport.initialize());
app.use(passport.session());
// Now we can access req.user so after we will call req.user, if we write it above these, it will always return underfined
app.use(function(req, res, next){
res.locals.user = req.user || null
next();
})
请参见,如果您要在passport.session()
之后访问req.user,请在下面添加路由。
答案 15 :(得分:0)
在进行session: true
时,您可以添加app.post("/login", passport.authenticate('local', {
'failureRedirect': '/login',
'session': true
}), (req, res)=>{ res.redirect("/"); });
来解决您的问题:
class Person extends Component {
render() {
return (
<div onClick={this.propes.onClick}>{this.props.children}</div>
)
}
}
答案 16 :(得分:0)
我的与所有这些都不一样。我以前曾在localhost上开发一个Wordpress站点,然后切换到一个单独的Node / React项目。
由于两个项目都在本地主机上运行,因此来自Wordpress网站的cookie仍然存在并正在发送。这就是问题所在。
我必须清除本地主机的cookie,然后它才能工作。
答案 17 :(得分:0)
我的两分钱: 无效的代码:
poll
工作代码:
server.use(
session({
secret: "secretsssss",
rolling: false,
resave: false,
saveUninitialized: false,
cookie: {
sameSite: true, //this line
maxAge: 60 * 60 * 1000
}
})
);
答案 18 :(得分:0)
对用户进行身份验证时,将填充请求值req.user
。要知道是否标识用户并填写该值,将使用cookie。
如果像我一样,您使用安全cookie配置会话,则cookie仅在HTTPS
上可用,这不是本地开发服务器的标准配置。要使Cookie在HTTP
上正常运行,请注释掉cookie: { secure: true }
,并正确配置req.user
的值:
this.app.use(session({
resave: true,
saveUninitialized: true,
secret: process.env.SESSION_SECRET || "a secret",
// cookie: { secure: true },
}));
如果合理地说,您只想在生产中使用Cookie超过HTTPS
,则可以执行以下操作:
cookie: { secure: process.env.ENV === 'PRODUCTION' }
答案 19 :(得分:0)
服务器发送SetCookie标头,然后通过浏览器句柄存储它,然后将Cookie与在HTTP HTTP标头内向同一服务器发出的请求一起发送。
我必须在客户端中设置withCredentials:true。 (axios.js)
const config = {
withCredentials: true,
headers: {
'Content-Type': 'application/json',
},
};
axios.put(url, { page: '123' }, config)
.then(res => console.log('axios', res))
.catch(err => console.log('axios', err));
然后发生CORS问题。
因此我将其添加到我的快递服务器中:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method) {
res.send(200);
} else {
next();
}
});
答案 20 :(得分:0)
您是否曾尝试在cookieParser中插入您的secretKey?
var passport = require('passport');
var expressSession = require('express-session');
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser('mySecretKey'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressSession({
secret: 'mySecretKey',
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
答案 21 :(得分:0)
遇到了同样的问题,但是我的原因更多是与误解passport.authorize
和passport.authenticate
在OAuth流和OAuth回调路由开始时的差异有关。
passport.authorize
不会影响req.user
变量,但是由于我只是复制并粘贴了该策略文档中的示例代码,所以我没有意识到使用了错误的方法。更改为passport.authenticate
后,用户变量可用。
希望这可以帮助在不知不觉中做同样事情的人。
答案 22 :(得分:0)
更改顺序:
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: true }));
对此:
app.use(bodyParser.urlencoded({ extended: true }));
app.set("view engine", "ejs");
答案 23 :(得分:0)
我在将cookie解析器与express-session一起使用时是这样的:
var express = require("express"); // 4.16.1
var cors = require("cors"); // 2.8.5
var cookieParser = require("cookie-parser"); // 1.4.4
var expressSession = require("express-session"); // 1.17.1
var app = express();
app.use(
cors({
origin: "http://localhost:3000",
credentials: true,
})
);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
expressSession({
secret: "secret123",
resave: true,
saveUninitialized: true,
cookie: { maxAge: 60 * 60 * 24 * 1000 },
})
);
app.use(cookieParser("secret123")); // this line
在快速会话之前放入cookie解析器对我有用,就像这样:
var express = require("express"); // 4.16.1
var cors = require("cors"); // 2.8.5
var cookieParser = require("cookie-parser"); // 1.4.4
var expressSession = require("express-session"); // 1.17.1
var app = express();
app.use(
cors({
origin: "http://localhost:3000",
credentials: true,
})
);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser("secret123"));
app.use(
expressSession({
secret: "secret123",
resave: true,
saveUninitialized: true,
cookie: { maxAge: 60 * 60 * 24 * 1000 },
})
);
答案 24 :(得分:0)
如果你的中间件堆栈不清楚,假设你有会话中间件某处,你可以在重定向之前保存会话:
if (req.user) {
req.session.save(function (err) {
if (err) {
// ... panic!
}
res.redirect("/user/" + req.user._id);
});
return;
}
答案 25 :(得分:-1)
我有一个不同的问题,有bcrpt-node和arrow函数。
有效的代码:
userSchema.methods.generateHash = function (password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
userSchema.methods.isValidPassword = function (password) {
return bcrypt.compareSync(password, this.password);
};
不起作用的代码:
userSchema.methods.generateHash = (password) => {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
userSchema.methods.isValidPassword = (password) => {
return bcrypt.compareSync(password, this.password);
};