在 firebase 实时数据库中存储没有用户特定安全规则的 firebase 用户身份验证令牌是否安全?

Is it safe to store a firebase user authentication token without user specific security rules in firebase realtime database?

我正在将 firebase Google OAuth 添加到我的 Electron 应用程序中 - 我已遵循此教程:https://pragli.com/blog/how-to-authenticate-with-google-in-electron/

一般的想法是启动 Electron 应用程序并单击“使用 google 登录”,创建一个 UUID,写入一个用这个 UUID 索引的 firebase 实时数据库条目并监听对此的更改入口。然后启动浏览器并在 URL 参数中传递 UUID。当页面加载时,调用 firebase 云函数(从浏览器应用程序)并将 UUID 传递给它。在云函数内部,可以引用数据库条目并将身份验证令牌写入数据库。

这是我在我的 Electron 应用程序中创建数据库引用的地方:

function createOAuthDatabaseEntry(
    auth: Auth,
    database: Database,
    electronAuthUuid: string,
): DatabaseReference | undefined {
    if (auth.currentUser) { // at this point in time the currentUser is null because they have not logged in
        const OAuthDatabaseRef = ref(
            database,
            `ot-auth-codes/${auth.currentUser?.uid}/${electronAuthUuid}`,
        );
        return OAuthDatabaseRef;
    }
}

然后监听变化:

function listenForBrowserSignIn(
    auth: Auth,
    OAuthDatabaseRef: DatabaseReference,
): Promise<{
    token: string;
    unsubscribeFromOAuthDatabaseChanges: Unsubscribe;
}> {
    return new Promise(resolve => {
        const unsubscribeFromOAuthDatabaseChanges = onValue(
            OAuthDatabaseRef,
            snapshot => {
                const token = snapshot.val();
                resolve({ token, unsubscribeFromOAuthDatabaseChanges });
            },
        );
    });
}

这是我的云函数代码:

exports.createAuthToken = functions.https.onCall(async (data, context) => {
    if (!context.auth) return { status: 'error', code: 401, message: 'Not signed in' };

    const decodedToken = await admin.auth().verifyIdToken(data.token);
    const authToken = await admin.auth().createCustomToken(decodedToken.uid);

    try {
        await admin
            .database()
            .ref(`ot-auth-codes/${context.auth.uid}/${data.code}`)
            .set(authToken);
        functions.logger.info('-------------> data sucessfully written to database')
    } catch (error) {
        functions.logger.error('-------------> error writing to database')
    }
});

我的问题是我正在尝试向数据库添加安全规则。到目前为止,我已经添加了 firebase docs:

中建议的这些
{
  "rules": {
    "some_path": {
      "$uid": {
        // Allow only authenticated content owners access to their data
        ".read": "auth != null && auth.uid == $uid",
        ".write": "auth != null && auth.uid == $uid"
      }
    }
  }
}

这是当 Electron 启动作为 React 应用程序的浏览器应用程序时调用云函数的地方:

function SignIn() {
    useEffect(() => {
        (async () => {
            try {
                const app = initializeApp(firebaseConfig);
                const functions = getFunctions(app);
                const provider = new GoogleAuthProvider();
                const auth = getAuth();
                const result = await getRedirectResult(auth)
                if (!result) {
                    signInWithRedirect(auth, provider)
                } else {
                    if (!result.user) {
                        return
                    }

                    const params = new URLSearchParams(window.location.search)
                    const token = await result.user.getIdToken()
                    const code = params.get("ot-auth-code")
                    const data = { token, code };
                    const createAuthToken = httpsCallable(functions, 'createAuthToken');
                    await createAuthToken(data)
                }
            } catch (error) {
                console.error('ERROR ----------------------->', error);
            }
        })()
    }, [])

我的问题是我无法使用这些特定规则来保护数据,因为在首次创建对数据库的引用时,用户未登录,因此 firebase 用户 uid 不可用.

我的问题是,删除此用例的用户特定数据库规则是否安全,或者我可以使用其他东西代替 uid 来保护数据吗?

你的做法是错误的。您的函数应该 return 将令牌直接发送给调用客户端代码作为其输出。然后客户端可以使用它来登录。您绝对不希望存储不受保护的身份验证令牌。那将是一个安全问题。

我建议查看 documentation 中描述的模式。