Passport google oauth 和 cookie-session 在每次登录 Express 应用程序后都会返回相同的用户

问题描述 投票:0回答:1

我正在使用 Passport google OAuth 将用户登录到我的应用程序中。一切正常;每次登录时都会获取用户配置文件。然而,尽管每次登录都会在回调函数中返回正确的配置文件,但发送到前端的用户对象并没有改变。

我已经尝试删除后端和前端的cookie,但仍然没有任何变化。

我的护照策略文件(passport-google.js):

const User = require('./models/auth')
const passport = require('passport')
const GoogleStrategy = require('passport-google-oauth20').Strategy;

passport.use( new GoogleStrategy({
   clientID: process.env.GOOGLE_CLIENT_ID,
   clientSecret: process.env.GOOGLE_CLIENT_SECRET,
   callbackURL: '/auth/google/callback', 
   passReqToCallback: true, 
}, (req, accessToken, refreshToken, profile, done) => {
   User.findOne({googleID: profile.id})
       .then((currentUser) =>{
           if(currentUser){
               // if user is already saved
               return done(null, currentUser)
           }else{
               // if user is not saved
               new User({
                   username: profile.displayName,
                   googleID: profile.id,
                   email: profile.emails[0].value
               })
               .save()
               .then((savedUser) => {
                   // console.log(savedUser)
                   return done(null, savedUser)
               })
           }
       }).catch((err) => {
           console.log('User not found!', err)
       })
}))

passport.serializeUser((user, cb)=>{
   console.log('users: ', user)
   return cb(null, user.id)
})

passport.deserializeUser(async(id, cb) =>{
   console.log('id: ' , id)
   const user = User.findOne({where: {_id: id}})
   .then((user)=>{
       cb(null, user)
   })
   .catch((err)=>{
       console.log(err)
       cb(err, null)
   })
})

路由器和控制器代码(authRouter.js):

const router = require('express').Router()
const passport = require('passport')

router.get('/logout', async(req, res) =>{
    if(req.user){
        req.logout()
        res.clearCookie("session", {path:"/",httpOnly:true})
        res.clearCookie("session.sig", {path:"/",httpOnly:true})
     
        return res.redirect('http://localhost:3000/')
    }else{
        res.status(200).send('User already logged out!')
    }
})


router.get('/login/success', async(req, res) => {
    if(req.user){
        res.status(200).json({
            success: true,
            message: 'Login success',
            user: req.user,
        })
    }else{
        res.status(401).json({
            success: false,
            message: 'You are not logged in',
        })
    }
})

router.get('/login/failed', (req, res) => {
    res.status(404).json({
        success: false,
        message: 'Login failed',
        user: false
    })
})

router.get('/google', passport.authenticate('google', {session: false ,scope: ['profile', 'email']}))

router.get('/google/callback', passport.authenticate('google',  {
        failureRedirect: '/login/failed',
        failureMessage: 'Login with Google failed! Try again.', 
        // session: false
    }), (req, res) =>{
    res.redirect('http://localhost:3000/', )
})

module.exports = router

app.js

require('dotenv').config()
const connectDB = require('./database/connect')
const express = require('express')
const cors = require('cors')
const cookieSession = require('cookie-session')
const passport = require('passport')
// const passportSetup = require('./passport')
const passportSetupStrategy = require('./passport-google')
const authRouter = require('./routers/authRouter')
const app  = express()

app.use(cookieSession({name: 'session', keys: [process.env.SESSION_KEY] ,maxAge: 24 * 60 * 60 * 1000}))
app.use(cors({
    origin: 'http://localhost:3000',
    credentials: true,
    methods: 'GET,PUT,POST,PATCH'
}))

// set encoding middleware
app.use(express.json())
app.use(express.static('public'))
app.use(express.urlencoded({extended: false}))

app.use(passport.initialize())
app.use(passport.session())
app.use('/auth', authRouter)

const mongoURI = process.env.MONGO_URI

const startServer = async() => {
    try {
        await connectDB(mongoURI)
        app.listen('5000', async() => {
            console.log('Server listening on port 5000')
        })
    } catch (error) {
        console.log(error)
    }
}

startServer()

前端代码: 应用程序.js:

import logo from './logo.svg';
import './App.css';
import { useEffect, useState } from 'react';
import Navbar from './components/Navbar/Navbar';
import { useDispatch } from 'react-redux';
import { getMovies } from './features/movie/movieSlice';
import {Routes, Route} from 'react-router-dom'
import { Home } from './pages/Home/Home';
import { MovieDetail } from './pages/MovieDetail/MovieDetail';
import Login from './pages/Login/Login';
import { setUser, clearUser } from './features/auth/authSlice';
import axios from 'axios';


function App() {
  const [isLoading, setIsLoading] = useState()
  const dispatch = useDispatch()
    useEffect(() => {
        dispatch(getMovies())
        const getUser = async() =>{
            fetch('http://localhost:5000/auth/login/success', {
              credentials: 'include',
              method: 'GET',
              headers: {
                Accept: 'application/json',
                'Content-Type': 'application/json',
                'Access-Control-Allow-Credential': true,
              },
            })
            .then((res)=>{
              return res.json()
            })
            .then((data) =>{
              console.log('received: ', data)
              dispatch(setUser(data.user))
            })
          .catch((error)=>{
              console.log(error)
              dispatch(clearUser())
          })
      }
      getUser()
    }, [])

  return (
    <div className='flex flex-col gap-5 relative bg-indigo-900'>
      <Navbar />
      <Routes>
        <Route path='/' element={<Home />}/>
        <Route path='/movie/:id' element={<MovieDetail />}/>
        <Route path='/login' element={<Login />}/>
      </Routes>
    </div>
  );
}

export default App;

Navbar.jsx:

import React from 'react'
import { FaHeart } from 'react-icons/fa'
import { useDispatch, useSelector } from 'react-redux'
import { Link } from 'react-router-dom'
import { clearUser } from '../../features/auth/authSlice'
import Favourites from '../Favourites/Favourites'
import './Navbar.css'

const Navbar = () => {
  const {user} = useSelector(store => store.auth)
  const dispatch = useDispatch()
  const logout = () =>{
    window.open('http://localhost:5000/auth/logout', '_self')
    document.cookie = null
    dispatch(clearUser())
  }

  return (
    <header className='header text-white flex justify-between items-center p-2 bg-indigo-500 lg:px-20'>
        <Link 
          className='text-center text-3xl font-bold'
          to='/'
        >
            <span className='bg-white text-indigo-900 p-2 shadow-lg shadow-black rounded-md'>M</span>Moviex
        </Link>
        {
          user? (
            <div className='flex gap-1 items-center'>
                <p>Hello, {user.username}</p>
                <Link 
                  className='bg-slate-400 p-2 rounded-md' 
                  onClick={logout}>Logout</Link>
            </div>
          ):(
            <Link to='/login'>Login</Link>
          )
        }
        <Favourites />
    </header>
  )
}

export default Navbar
javascript node.js express session-cookies passport-google-oauth2
1个回答
0
投票

添加此: 护照.use( 新的 GoogleStrategy({ ... 提示:'选择帐户', ...

© www.soinside.com 2019 - 2024. All rights reserved.