【问题标题】:Why can't I access req.user in passport.use()?为什么我不能在 passport.use() 中访问 req.user?
【发布时间】:2023-01-24 02:13:06
【问题描述】:

我正在编写一个小型电子商务应用程序,使用 PostgreSQL 数据库通过 Google 进行第三方登录。这是我的谷歌策略配置:

const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy;
passport.use(new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: `${process.env.NODE_ENV === "production" ? [production URL] : "http://localhost:8000"}/api/auth/login/google/callback`,
    passReqToCallback: true,
    scope: ["email", "profile"]
}, db.third.login));

这是下面的 db.third.login,它与通过 Google 验证自己的新注册用户和现有用户完美配合。除了对用户进行身份验证外,它还会传递最终强制新注册用户在使用该应用程序之前在客户端中设置电话号码和密码的信息。

const login = async(req, accessToken, refreshToken, profile, done) => {
    // Get request IP address
    const ip = requestIP.getClientIp(req);

    // Generate login attempt ID
    const attemptId = idGen(15);

    try { // Get federated credentials
        let result = await pool.query("SELECT * FROM federated_credentials WHERE id = $1 AND provider = $2", [profile.id, profile.provider]);

        // Create user account if credentials don't exist
        if (result.rows.length === 0) {
            // Send error if email already exists in database
            result = await pool.query("SELECT email FROM users WHERE email = $1", [profile.emails[0].value]);
            if (result.rows.length > 0) return done({ status: 409, message: "Error: A user with the provided email already exists." });

            // Generate user ID and cart ID
            const userId = idGen(7);
            const cartId = idGen(7);

            // Generate password hash
            const salt = await bcrypt.genSalt(17);
            const passwordHash = await bcrypt.hash(process.env.GENERIC_PASSWORD, salt);

            // Add user to database
            let text = `INSERT INTO users (id, first_name, last_name, phone, email, password, created_at) VALUES ($1, $2, $3, $4, $5, $6, to_timestamp(${Date.now()} / 1000)) RETURNING id`;
            let values = [userId, profile.name.givenName, profile.name.familyName, "254700000000", profile.emails[0].value, passwordHash];
            result = await pool.query(text, values);

            // Add user cart to database
            result = await pool.query("INSERT INTO carts (id, user_id) VALUES ($1, $2)", [cartId, userId]);

            // Add federated credentials to database
            result = await pool.query("INSERT INTO federated_credentials (id, provider, user_id) VALUES ($1, $2, $3)", [profile.id, profile.provider, userId]);

            // Add user details to be confirmed to session
            const federatedCredentials = { id: profile.id, provider: profile.provider, confirm: true };
            return done(null, { id: userId, email: profile.emails[0].value, role: "customer", cartId: cartId, federatedCredentials });
        }

        // Save federated credentials details
        const federatedCredentials = { id: result.rows[0].id, provider: result.rows[0].provider, confirm: !result.rows[0].confirmed };

        // Get user details
        result = await pool.query("SELECT users.id AS id, users.email AS email, users.password AS password, users.role AS role, carts.id AS cart_id FROM users JOIN carts ON carts.user_id = users.id WHERE email = $1", [profile.emails[0].value]);

        // Log login attempt
        await loginAttempt(attemptId, ip, profile.emails[0].value, "google", true);

        // Add user to session
        return done(null, { id: result.rows[0].id, email: result.rows[0].email, role: result.rows[0].role, cartId: result.rows[0].cart_id, federatedCredentials });
    } catch (err) {
        return done({ status: 500, message: "An unknown error occurred. Kindly try again." });
    }
}

我现在想添加允许现有用户(以其他方式注册的用户)链接他们的 Google 帐户的功能,但我的问题是 req.user 显然无法在 passport.use() 中访问(控制台日志显示它是 undefined 甚至在我登录之后)。如何在passport.use() 中访问会话中当前用户的信息以实现此目的? (或者完全有另一种解决方案?)

【问题讨论】:

    标签: node.js express passport.js


    【解决方案1】:

    Passport repository on GitHub 进行了一些挖掘,发现一位用户报告将 express-session cookie 对象中的 sameSite 属性设置为 "lax" 作为可行的解决方案,它对我也有效。你可以read the comment here

    const session = require("express-session");
    app.use(session({
        ... // other session options
        cookie: {
            ... // other cookie options
            sameSite: "lax" 
        }
    }))
    

    希望 Jared Hanson 先生能尽快提供最新情况说明原因(以及允许从 passport.use() 无条件访问 req.user 的修复程序)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2014-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-19
      • 1970-01-01
      相关资源
      最近更新 更多