mongodb - 为什么我的 req.user 没有保存在旧版 Chrome 上?
问题描述
我正在使用 passportjs 和 express 来处理我的身份验证。我有一些用户运行旧版本(但不是那么旧)的 chrome 无法登录。我进行了一些测试,我使用的是 Chrome v77,它运行良好,但如果我下载并使用 Chrome v60,req.user
则不会保存。换句话说,用户进行了身份验证,但是当他们从重定向到/login
对象时没有信息。这是我的快速设置:/admin
req
user
import path from "path";
import bodyParser from "body-parser";
import compression from "compression";
import connectMongo from "connect-mongo";
import cookieParser from "cookie-parser";
import errorhandler from "errorhandler";
import express from "express";
import session from "express-session";
import methodOverride from "method-override";
import mongoose from "mongoose";
import logger from "morgan";
import passport from "passport";
import passportLocal from "passport-local";
import Config from "./config";
import User from "./models/user";
import Routes from "./routes";
const LocalStrategy = passportLocal.Strategy;
const MongoStore = connectMongo(session);
const DIST_DIR = __dirname;
const HTML_FILE = path.join(DIST_DIR, "front.html");
const ADMIN_HTML_FILE = path.join(DIST_DIR, "admin.html");
// mongoose
mongoose.Promise = global.Promise;
mongoose.connect(Config.uristring, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false
});
// express
const app = express();
app.use(compression());
app.use(express.static(DIST_DIR));
// for parsing application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: true}));
// parse application/json
app.use(
bodyParser.json({
// Because Stripe needs the raw body, we compute it but only when hitting the Stripe callback URL.
verify(req, res, buf) {
const url = req.originalUrl;
if (url.startsWith("/stripeWebhook")) {
req.rawBody = buf.toString();
}
}
})
);
// parse some custom thing into a Buffer
// app.use(bodyParser.raw({type: "*/*"})); // TO DO : needed?
// logging
app.use(logger("tiny"));
app.use(methodOverride());
app.use(cookieParser("supersecret"));
app.use(
session({
secret: "supersecret",
maxAge: new Date(Date.now() + 3600000),
store: new MongoStore({mongooseConnection: mongoose.connection}),
resave: true,
saveUninitialized: true
// cookie: {
// path: "/",
// domain: "." + Config.domain
// }
})
);
// app.use(express.static(path.join(DIST_DIR)));
// passport config
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
const env = process.env.NODE_ENV || "development";
if (env === "development") {
app.use(errorhandler({dumpExceptions: true, showStack: true}));
} else if (env === "production") {
app.use(errorhandler());
}
// routes
Routes(app);
app.get("/admin*", (req, res) => {
if (!req.user) { // <-- this returns true when usng Chrome v60
res.redirect("/Login");
} else {
res.sendFile(ADMIN_HTML_FILE);
}
});
app.get("*", (req, res) => {
res.sendFile(HTML_FILE);
});
const PORT = process.env.PORT || 1337;
app.listen(PORT, () => {
console.log(`Express server listening on port ${PORT}`);
});
这是我的登录路线:
app.post("/login", usernameToLowerCase, (req, res) => {
// console.log("/login");
passport.authenticate("local", (error, user) => {
if (error) {
console.error(error);
return Utils.handleError(
res,
"That email and password combination is invalid. Try something else.",
{
error_code: 400,
error_message:
"That email and password combination is invalid. Try something else."
},
400
);
}
if (!user) {
return Utils.handleError(
res,
"That email and password combination is invalid. Try something else.",
{
error_code: 400,
error_message:
"That email and password combination is invalid. Try something else."
},
400
);
}
req.logIn(user, error2 => {
if (error2) {
console.error("req.logIn()", error2);
}
console.log("user", user); // <-- this prints the users infomation, aka, the user is authenticated.
return res.status(200).end();
});
})(req, res);
});
用户通过身份验证后,客户端代码将他们重定向到/admin
上面的代码app.get("/admin*", (req, res) => {...})
中req.user
未定义的。为什么它适用于新版本的 Chrome 而不是旧版本?
10 月 4 日更新
我比较了req
旧版 chrome 和最新版 chrome 的对象,除了标题对象(粘贴在下面)之外,没有太大区别。我看到的主要区别在于该accept
领域。最新版本的 Chrome 包括application/signed-exchange;v=b3
. 不确定这是否意味着什么。
// Chrome/60.0.3112.113
req IncomingMessage {
...,
headers:
{ host: 'site:1337',
connection: 'keep-alive',
'upgrade-insecure-requests': '1',
'user-agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
referer: 'http://site:1337/login',
'accept-encoding': 'gzip, deflate',
'accept-language': 'en-US,en;q=0.8',
cookie:
'connect.sid=s%3AZZ4Qhv0l1_i6Uj1lOsSe3U35L_x3ZjOv.PXHfo31JeXMryrVhzjUk7ddDYVjrgXR3fce9zvKR3r4; driftt_sid=124ef61a-e1c6-4e69-aa0b-dfcfadbf1f94; driftt_aid=4386675a-47d7-48f6-96e6-179a31102685; DFTT_END_USER_PREV_BOOTSTRAPPED=true; _ga=GA1.1.1260521767.1570198850; _gid=GA1.1.1188015175.1570198820; _gat_UA-2415456-23=1' },
}
// Chrome/77.0.3865.90
req IncomingMessage {
...,
headers:
{ host: 'site:1337',
connection: 'keep-alive',
'upgrade-insecure-requests': '1',
'user-agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
referer: 'http://site:1337/login',
'accept-encoding': 'gzip, deflate',
'accept-language': 'en-US,en;q=0.9',
cookie:
'driftt_aid=f6726983-a2b0-4f41-881c-645c79004bfa; DFTT_END_USER_PREV_BOOTSTRAPPED=true; _ga=GA1.1.1244515219.1561402493; driftt_eid=asdf%40gmail.com; __insp_uid=2317814610; _gid=GA1.1.1763411286.1570046360; __insp_wid=1206788101; __insp_nv=false; __insp_targlpu=aHR0cDovL3NpaGU6MTMzNy9hZG1pbi9zZXR0aW5ncw%3D%3D; __insp_targlpt=QXV0b21hdGVkIE1lc3NhZ1luZyAmIEludGVsbGlnZW50IFByaWNpbmcgRm9yIEFpcmJuYiBIb3N0cw%3D%3D; __insp_pad=1; __insp_sid=2173009741; __insp_slim=1570046108183; driftt_sid=65747fd5-73e1-466f-acf0-c9012cf3a398; connect.sid=s%3APNsX1PZ7JiQ0RHI8Np3ftq9_izaxL5tv.LxoBtGmKbq9SgMER1Fs99CGEOGVkOrjq0syQoTicNQI; _gat_UA-2415456-23=1' },
}
我还在代码中记录了req
对象,它在调用之前将对象req.logIn(user, error2 => {...})
保存到user
对象中。希望有帮助。req
return res.status(200).end();
解决方案
尝试将此代码添加到您的代码中:
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
db.accounts.findById(id, function(err, user){
return done(err, user);
});
});
推荐阅读
- ios - React Native App 在 iPad 3rd Generation 中具有黑色边框而不是边缘到边缘全屏
- file - 重置文件柜中 CSV 文件的内容
- javascript - 从客户端 JS 脚本以编程方式控制 Outlook
- javascript - 当表单已经为 [disabled] 字段设置了 form.valid 字段时,在提交表单后禁用按钮
- javascript - 使用内联样式在 React Native 中定位组件
- wordpress - 如何在 Contact Form 7 中添加没有 JS 的自定义属性?
- java - 向 Logback 添加阈值过滤器
输出? - json - 在 JSON 调用后努力保存数据
- python - 使用基于地图的碰撞检测 Pygame 滚动背景
- ruby-on-rails - 如何处理 ActiveRecord::RecordNotUnique 错误