使用PassportJS实现Google登录后,前端无法获取用户数据
问题分析与解决方案
核心问题
你当前的代码里,window.open("http://localhost:4000/auth/google/callback", "_self")会直接跳转页面,当前页面的JS上下文被销毁,后续的axios请求根本不会执行,这就是你无法获取数据的原因。
解决方案
方案1:页面跳转后自动拉取用户信息
后端在Google登录成功后,重定向回你的前端页面(比如http://localhost:3000/home),然后在前端页面初始化时请求用户信息:
import { useEffect } from 'react'; import axios from 'axios'; import { useDispatch } from 'react-redux'; function HomePage() { const dispatch = useDispatch(); useEffect(() => { const fetchUserInfo = async () => { dispatch({ type: "LOGIN_START" }); try { // 关键:携带cookie,Passport通过会话cookie识别已登录用户 const result = await axios.get("http://localhost:4000/login/success", { withCredentials: true }); dispatch({ type: "LOGIN_SUCCESS", payload: result.data }); } catch (err) { dispatch({ type: "LOGIN_FAILURE", payload: err.message }); } }; fetchUserInfo(); }, [dispatch]); // 页面渲染逻辑... }
方案2:弹窗式登录(不跳转当前页面)
如果不想跳转当前页面,可以用弹窗打开登录流程,监听弹窗关闭后再拉取数据:
const googleSignIn = (e) => { e.preventDefault(); dispatch({ type: "LOGIN_START" }); // 打开Google授权弹窗 const loginPopup = window.open( "http://localhost:4000/auth/google", "_blank", "width=600,height=650" ); // 定时检查弹窗状态 const checkPopup = setInterval(() => { if (loginPopup.closed) { clearInterval(checkPopup); // 弹窗关闭后请求用户信息 axios.get("http://localhost:4000/login/success", { withCredentials: true }) .then(res => { dispatch({ type: "LOGIN_SUCCESS", payload: res.data }); }) .catch(err => { dispatch({ type: "LOGIN_FAILURE", payload: err.message }); }); } }, 1000); };
关键注意事项
- 后端必须配置CORS,允许你的前端域名,并且开启
credentials: true,否则cookie无法传递 - 后端的Passport Google策略要正确配置会话存储,确保登录成功后会话能被正确识别
内容的提问来源于stack exchange,提问作者sultan.h
相关产品推荐
相关产品推荐

