You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GAS集成Firebase谷歌认证后登录状态下的流程及最佳实践咨询

Firebase谷歌认证集成到Google Apps Script Web应用的最佳实践问题与解答

问题描述

我正在尝试将Firebase谷歌认证集成到基于Google Apps Script(GAS)的Web应用中,作为开发新手,目前遇到了一些困难。我已完成部分步骤,但用户登录后无法正常导航应用。

已实现的正常流程

  • doGet()返回HtmlService.createHtmlOutputFromFile('auth'),包含所有认证必要代码;
  • 'auth.html'通过CDN调用Firebase相关资源,未登录时显示认证UI,登录后显示用户详情;
  • 已将userID传递到服务端用于验证,但不确定此方式是否正确。

咨询的最佳实践问题

  1. 用户打开应用后,doGet()加载auth.html完成客户端认证并获取用户数据、传递userID到服务端后,如何加载实际应用内容?是否应通过google.script.run.someFunction(userID)调用相关函数加载原应用内容?
  2. 是否需要在每个页面加载前都执行认证?

相关代码示例

.gs 文件

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('auth2')
  .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
  .setTitle('FirebaseUI | Firebase Authentication');
}

auth.html 文件

<base target="_top">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://www.gstatic.com/firebasejs/7.14.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.2/firebase-auth.js"></script>
<script src="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css" />
<script>
    var firebaseConfig = {
      apiKey: "stackoverflow",
      authDomain: "stackoverflow.firebaseapp.com",
      databaseURL: "https://stackoverflow-default-rtdb.europe-west1.firebasedatabase.app",
      projectId: "stackoverflow",
      storageBucket: "stackoverflow.appspot.com",
      messagingSenderId: "267227785525",
      appId: "1:stackoverflow:web:stackoverflow",
      measurementId: "G-stackoverflow"
    };
    firebase.initializeApp(firebaseConfig);
</script>
<script>
    google.script.run.withSuccessHandler(function(url) {
        var uiConfig = {
            signInFlow: 'redirect',
            signInSuccessUrl: url,
            signInOptions: [
                firebase.auth.GoogleAuthProvider.PROVIDER_ID
            ],
        };
        var ui = new firebaseui.auth.AuthUI(firebase.auth());
        var user = firebase.auth().currentUser;
        console.log(user);
        if (user) {
            document.getElementById("signOut").style.display = "inline-block";
        } else {
            ui.start('#firebaseui-auth-container', uiConfig);
        }
    })
    .webAppUrl();
</script>
<script>
    initApp = function() {
        firebase.auth().onAuthStateChanged(function(user) {
            if (user) {
                user.getIdToken().then(function(accessToken) {
                    document.getElementById('account-details').textContent = JSON.stringify({
                        displayName: user.displayName,
                        email: user.email,
                        custom: user.email,
                        emailVerified: user.emailVerified,
                        phoneNumber: user.phoneNumber,
                        photoURL: user.photoURL, // remove quotes to get the photoURL
                        uid: user.uid,
                        accessToken: "hidden", // replace "hidden" with accessToken
                        providerData: user.providerData // remove quotes to get the photoURL
                    }, null, '  ');
                });
              const userID = user.email;
              google.script.run.someFunction(userID);
            } else {
                document.getElementById('account-details').textContent = '';
            }
        });
    };
    window.addEventListener('load', function() {
        initApp();
    });
</script>
</head>

解答

1. 登录后加载实际应用内容的方式

你当前用google.script.run.someFunction(userID)的思路可行,但可以优化得更安全合理:

  • 方案一:客户端动态替换内容:在服务端写一个getAppContent(userToken)函数,传入Firebase的ID Token而非仅userID(避免伪造),验证通过后返回主应用页面的HTML片段;客户端拿到片段后,用DOM操作替换当前页面的认证内容区域(比如把#firebaseui-auth-container的innerHTML替换为返回的内容)。
  • 方案二:页面跳转+服务端路由:认证完成后,客户端通过window.location.href = '?action=loadApp'跳转;在doGet(e)中判断e.parameter.action,如果是loadApp则先验证用户的ID Token,合法后返回主应用页面,否则重定向到认证页面。
  • 关键注意:仅传递userID到服务端不安全,必须用Firebase的ID Token做身份验证,服务端通过Firebase Admin SDK校验Token的有效性。

2. 是否需要每次页面加载前执行认证

是的,必须在每次页面加载前执行认证:

  • GAS Web应用是无状态的,每次请求都是独立会话,服务端无法保存用户登录状态;
  • 客户端的Firebase登录状态可能过期、被用户主动退出,每次加载页面时通过onAuthStateChanged检查能确保用户状态有效;
  • 服务端处理任何敏感请求前,都要重新验证ID Token,避免未授权访问。

内容的提问来源于stack exchange,提问作者LeSmoox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 06:50:24