首页 > 解决方案 > 为什么我的 req.user 没有保存在旧版 Chrome 上?

问题描述

我正在使用 passportjs 和 express 来处理我的身份验证。我有一些用户运行旧版本(但不是那么旧)的 chrome 无法登录。我进行了一些测试,我使用的是 Chrome v77,它运行良好,但如果我下载并使用 Chrome v60,req.user则不会保存。换句话说,用户进行了身份验证,但是当他们从重定向到/login对象时没有信息。这是我的快速设置:/adminrequser

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对象中。希望有帮助。reqreturn res.status(200).end();

标签: mongodbexpresspassport.js

解决方案


尝试将此代码添加到您的代码中:

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

推荐阅读