Express 在google passport回调后设置cookie

Express 在google passport回调后设置cookie,express,passport.js,passport-google-oauth,Express,Passport.js,Passport Google Oauth,我正在使用和登录使用,使用这个流 用户单击了登录按钮 重定向到facebook/google身份验证页面(取决于用户选择的登录方式) 身份验证页面重定向回回调页面(/auth/callback/[provider]) passport express中间件将捕获它以解析一些数据,然后将其发送到myown的远程api以登录用户 auth remote api将发送一个包含用户令牌的响应 自定义express中间件将捕获服务器上设置cookie的响应 express链通过将其路由到/profile(

我正在使用和登录使用,使用这个流

  • 用户单击了登录按钮
  • 重定向到facebook/google身份验证页面(取决于用户选择的登录方式)
  • 身份验证页面重定向回回调页面(
    /auth/callback/[provider]
  • passport express中间件将捕获它以解析一些数据,然后将其发送到myown的远程api以登录用户
  • auth remote api将发送一个包含用户令牌的响应
  • 自定义express中间件将捕获服务器上设置cookie的响应
  • express链通过将其路由到
    /profile
    (浏览器上设置了带有令牌的cookie)而结束
  • /profile
    然后将检查是否有令牌,如果没有:它将重定向到
    /
  • 在登录时执行此流程很好,用户成功重定向到
    /profile
    ,以及其所有数据和令牌,但是登录似乎正在重定向到
    /profile
    ,然后设置令牌(第7步,然后第6步),因此每次用户使用登录时,它总是会被重定向回
    /
    ,因为当它到达
    /profile
    时,它没有令牌

    下面是上面流程中的代码

    #/server.js

    const express = require('express')
    const next = require('next')
    const Passport = require('./server/middleware/passport')
    
    const Api = require('./server/api')
    
    const port = parseInt(process.env.PORT, 10)
    const dev = process.env.NODE_ENV !== 'production'
    const app = next({ dev })
    const handle = app.getRequestHandler()
    
    app
      .prepare()
      .then(() => {
        const server = express()
        // ... other unrelated things
        server.use(Passport.initialize())
    
        Api.passport.facebook(server)
        Api.passport.facebookCallback(server)
        Api.passport.google(server)
        Api.passport.googleCallback(server)
    
        // ... other unrelated things
    
        server.all('*', (req, res) => handle(req, res))
    
        server.listen(port, (error) => {
          if (error) throw error
    
          // ... other unrelated things
        })
      })
    
    #/server/api.js

    const Passport = require('middleware/passport')
    
    function setCookie(req, res, next) {
      res.cookie('token', req.user.auth.token, {
        httpOnly: true,
        sameSite: 'strict',
        path: '/',
        secure: process.env.NODE_ENV !== 'development',
      })
      next()
    }
    
    function facebook(app) {
      return app.get('/auth/facebook', (req, res, next) => {
        Passport.authenticate('facebook', {
          scope: ['email', 'public_profile']
        })(req, res, next)
      })
    }
    
    function facebookCallback(app) {
      return app.get(
        '/auth/callback/facebook',
        Passport.authenticate('facebook', { session: false, failureRedirect: '/' }),
        setCookie,
        (req, res) => {
          res.redirect('/profile')
        },
      )
    }
    
    function google(app) {
      return app.get('/auth/google', (req, res, next) => {
        Passport.authenticate('google', {
          scope: [
            'https://www.googleapis.com/auth/userinfo.email ',
            'https://www.googleapis.com/auth/userinfo.profile ',
          ],
          prompt: 'consent',
          authType: 'rerequest',
          accessType: 'offline',
        })(req, res, next)
      })
    }
    
    function googleCallback(app) {
      return app.get(
        '/auth/callback/google',
        Passport.authenticate('google', { failureRedirect: '/', session: false }),
        setCookie,
        (req, res) => {
          res.redirect('/profile')
        },
      )
    }
    
    module.exports = {
      passport: {
        facebook,
        facebookCallback,
        google,
        googleCallback,
      }
    }
    
    #./server/middleware/passport.js

    const axios = require('axios')
    const passport = require('passport')
    const GoogleStrategy = require('passport-google-oauth20').Strategy
    const FacebookStrategy = require('passport-facebook').Strategy
    
    
    passport.serializeUser((user, done) => {
      done(null, user)
    })
    
    passport.deserializeUser((obj, done) => {
      done(null, obj)
    })
    
    function verifyCallback(req, ... , done) {
      process.nextTick(async () => {
        try {
          const options = {
            baseURL: baseUrl, // My remote api url
            method: 'POST',
            url: '/auth/signin',
            headers: {
              'Content-Type': 'application/json',
            },
            data: JSON.stringify({
              // email, fullname, etc
            }),
          }
          const response = await axios(options)
    
          return done(null, response.data)
        } catch (error) {
          const { response } = error
          return done(JSON.stringify(response.data, null, 2), null)
        }
      })
    }
    
    passport.use(new GoogleStrategy({
      clientID: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: callbackURLGoogle,
      passReqToCallback: true,
    }, verifyCallback))
    
    passport.use(new FacebookStrategy({
      clientID: process.env.FACEBOOK_CLIENT_ID,
      clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
      callbackURL: callbackURLFacebook,
      enableProof: true,
      profileFields: ['id', 'name', 'email', 'picture.type(large)'],
      passReqToCallback: true,
    }, verifyCallback))
    
    module.exports = passport
    
    I
    console.log()
    things,只是为了弄清楚它是否属于正确的流顺序,控制台似乎没有记录任何可疑的内容,这里有我遗漏的东西吗


    PS:我也在使用

    您是否尝试使用async并等待发送请求的函数?它会告诉函数等待响应。哪个函数?设置cookie的那个?你在登录Google时没有问题吗?然后,您的谷歌策略将失败转移到
    “/”
    。(请参阅
    Passport.authenticate('google',{failureRedirect:'/',session:false}),
    你有Google开发者控制台中的所有设置吗?你的callbackURLGoogle地址是什么?@Fide没有,我登录Google没有问题,我可以在上面的
    verifyCallback
    函数中确认,它也到达了我的远程验证api并得到了成功响应,它转到
    //code>的原因不是因为
    failureRedirect
    但是因为在
    /account
    上,我检查了是否有令牌cookie,如果没有重定向到
    /
    你能在setCookie?Passport文档中记录
    req.user.auth.token
    :Passport.user(新谷歌策略(),-->函数(accessToken,refreshToken,profile,done)