谷歌登录拦截封禁用户问题:signInWithRedirect后未执行校验逻辑
聊天应用封禁系统登录拦截问题解决
问题根源
使用signInWithRedirect()时,页面会发生跳转,原异步函数中await之后的代码会因页面刷新、上下文丢失而无法执行,导致封禁校验逻辑完全没触发。
解决方案
1. 简化登录触发函数
只负责发起Google登录跳转,后续逻辑移到页面加载时处理:
const googleProvider = new GoogleAuthProvider(); const signInWithGoogle = () => { signInWithRedirect(auth, googleProvider); };
2. 在LoginPage中处理登录结果与封禁校验
利用useEffect在组件加载时,通过getRedirectResult()获取登录结果,同时处理页面刷新后已登录用户的封禁检查:
import { useEffect } from 'react'; import { getRedirectResult, signOut, useAuthState } from 'firebase/auth'; import { query, collection, where, getDocs } from 'firebase/firestore'; import { auth, db } from './firebase-config'; // 替换为你的Firebase配置路径 import { useNavigate } from 'react-router-dom'; function LoginPage() { const [user] = useAuthState(auth); const navigate = useNavigate(); useEffect(() => { const checkBanStatus = async () => { // 处理重定向登录的结果 const redirectResult = await getRedirectResult(auth); let targetUser = redirectResult?.user || user; if (targetUser) { // 查询banned集合,检查用户是否被封禁 const banQuery = query(collection(db, "banned"), where("uid", "==", targetUser.uid)); const querySnapshot = await getDocs(banQuery); // 注意:QuerySnapshot用empty判断是否有匹配文档,单个文档才用exists() if (!querySnapshot.empty) { console.log('你已被封禁,无法使用本应用'); await signOut(auth); navigate('/'); } else { // 未被封禁,跳转到应用主页 navigate('/chat'); } } }; checkBanStatus(); }, [user, navigate]); return ( <div> <div style={{ display: 'none' }}> <Navbar /> </div> <Welcome /> </div> ); }
3. 修正退出登录逻辑
确保退出操作完成后再跳转页面:
const navigate = useNavigate(); const signOutWithGoogle = async () => { await signOut(auth); navigate('/'); };
关键注意点
signInWithRedirect()不会在原函数中返回结果,必须通过getRedirectResult()在页面重新加载后获取登录信息- Firestore中用
getDocs()查询集合返回的是QuerySnapshot,判断是否存在匹配文档需用!querySnapshot.empty,exists()是单个DocumentSnapshot的方法 - 要覆盖两种场景:刚完成重定向登录的用户,以及页面刷新后仍处于登录状态的用户,都需要做封禁校验
内容的提问来源于stack exchange,提问作者an1me. graphics
相关产品推荐
相关产品推荐

