React中借助Firebase Functions实现Discord OAuth2弹窗登录流程
问题原因
HttpsCallable 类型的云函数是用于前后端JSON数据交互的,服务端返回的redirect响应会被Firebase SDK直接解析处理,不会触发浏览器跳转或者弹窗行为,所以你之前的调用方式无法实现预期效果。
正确实现步骤
- 第一步:把现有的鉴权逻辑云函数改成普通HTTPS触发的云函数,不要用Callable类型,函数内保留返回
response.redirect(discordAuthRedirectLink)的逻辑即可,部署后拿到该云函数的公网访问URL。 - 第二步:前端点击登录按钮的回调逻辑修改为打开新弹窗,地址指向上面的HTTPS云函数URL,示例代码:
const handleDiscordLogin = () => { // 打开固定尺寸的弹窗,避免被浏览器拦截 const authWindow = window.open( "你的HTTPS云函数URL", "discordAuth", "width=600,height=800,top=100,left=200" ); // 监听弹窗关闭的回调,轮询检测弹窗状态 const checkWindowClosed = setInterval(() => { if (authWindow.closed) { clearInterval(checkWindowClosed); // 这里调用Firebase Auth的currentUser reload接口,同步最新的登录状态 auth.currentUser?.reload().then(() => { // 登录状态更新后执行你的后续逻辑,比如跳转首页 }); } }, 1000); };
- 第三步:修改Discord授权成功后的回调云函数逻辑,拿到Discord返回的授权码后,通过Firebase Admin SDK生成自定义登录令牌,然后在回调页返回一段关闭弹窗的JS代码即可,示例逻辑:
// 回调云函数内的逻辑示例 const token = await admin.auth().createCustomToken(uid); response.send(` <script> // 把自定义令牌传给父窗口的Firebase Auth完成登录 window.opener.firebase.auth().signInWithCustomToken('${token}'); // 关闭当前弹窗 window.close(); </script> `);
注意事项
- 弹窗触发必须是用户点击行为的同步回调里执行
window.open,如果放在异步请求的回调里执行会被大部分浏览器的弹窗拦截规则拦截。 - 云函数的域名需要和你的前端应用域名配置到Firebase的授权域名列表中,避免跨域问题。
内容的提问来源于stack exchange,提问作者V. Recour
相关产品推荐
相关产品推荐

