Passport & JWT & Google 策略 - 在 google 回调后禁用会话 & res.send()

Passport & JWT & Google Strategy - Disable session & res.send() after google callback

使用:passport-google-oauth2.

我想使用 JWT with Google login - for that I need to disable session 并以某种方式将用户模型传递回客户端。 所有示例都使用 google 回调 magically redirect to '/'.

我如何:
1. 使用 passport-google-oauth2.
时禁用会话 2. res.send() 用户到客户端 google 认证后。

如果我的方向不对,请随时提出替代方案。

通过一些见解设法克服这个问题:
1. 在 express 中禁用会话 - 只需删除会话的中间件

// app.use(session({secret: config.secret}))

2。当使用 Google 身份验证时,实际发生的是重定向到 google 登录页面,如果登录成功,它会将您重定向回您提供的 url。

这实际上意味着一旦 google 调用你的回调,你就不能 res.send(token, user) - 它根本不起作用(任何人都可以详细说明为什么?)。因此,您被迫通过 res.redirect("/") 重定向到客户端。 但整个目的是传递令牌,因此您也可以执行 res.redirect("/?token=" + token).

app.get( '/auth/google/callback',
        passport.authenticate('google', {
            //successRedirect: '/',
            failureRedirect: '/'
            , session: false
        }),
        function(req, res) {
            var token = AuthService.encode(req.user);
            res.redirect("/home?token=" + token);
        });

但是客户端如何获取用户实体呢? 所以你也可以用同样的方式传递用户,但我觉得不合适(在参数列表中传递整个用户实体......)。 所以我所做的是让客户端使用令牌并检索用户。

    function handleNewToken(token) {
        if (!token)
            return;

        localStorageService.set('token', token);

        // Fetch activeUser
        $http.get("/api/authenticate/" + token)
            .then(function (result) {
                setActiveUser(result.data);
        });
    }

这意味着另一个 http 请求 - 这让我觉得我可能没有理解令牌的概念。 不吝赐教。

在index.js初始化护照:

app.use(passport.initialize());

在您的 passport.js 文件中:

passport.use(
new GoogleStrategy(
{
 clientID: process.env.GOOGLE_CLIENT_ID,
 clientSecret: process.env.GOOGLE_CLIENT_SECRET,
 callbackURL: 
'http://localhost:3000/auth/google/redirect',
},
async (accessToken, refreshToken, profile, 
callback) => {
  // Extract email from profile
  const email = profile.emails![0].value;

  if (!email) {
    throw new BadRequestError('Login failed');
  }

  // Check if user already exist in database
  const existingUser = await User.findOne({ email 
});

  if (existingUser) {
    // Generate JWT
    const jwt = jwt.sign(
      { id: existingUser.id },
      process.env.JWT_KEY,
      { expiresIn: '10m' }
    );

    // Update existing user
    existingUser.token = jwt
    await existingUser.save();

    return callback(null, existingUser);
  } else {

    // Build a new User
    const user = User.build({
      email,
      googleId: profile.id,
      token?: undefined
    });

    // Generate JWT for new user
      const jwt = jwt.sign(
      { id: user.id },
      process.env.JWT_KEY,
      { expiresIn: '10m' }
    );
   
    // Update new user
    user.token = jwt;

    await auth.save();

    return callback(null, auth);
  }
}));

通过 req.user

在路由中接收此 JWT
app.get('/google/redirect', passport.authenticate('google', 
{failureRedirect: '/api/relogin', session: false}), (req, res) => {
// Fetch JWT from req.user
const jwt = req.user.token;
req.session = {jwt}
// Successful authentication, redirect home
res.status(200).redirect('/home');
}