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

启用App Check的Firebase可调用函数返回"unauthenticated"错误求助

问题描述

调用Firebase Cloud Functions的uploadPhotoLimit函数时,客户端收到[firebase_functions/unauthenticated] UNAUTHENTICATED错误,Google Cloud日志提示"请求未被授权调用该服务"。已尝试为函数设置allAuthenticatedUsers权限、删除并重新部署函数,但问题仍未解决。因不想使用allUsers权限(会绕过App Check验证,降低安全性),寻求可行解决方案。

客户端代码

class FirebasePublicationRepository implements PublicationRepository {
  @override
  Future<String> publishPost({
    required String postType, // "friends" ou "public"
    required String imagePath,
    required String title,
    required String description,
  }) async {
    final User? user = FirebaseAuth.instance.currentUser;
    if (user == null) {
      throw Exception("L'utilisateur n'est pas authentifié.");
    }

    final appCheckToken = await FirebaseAppCheck.instance.getToken();
    if (appCheckToken == null) {
      throw Exception("App Check token is missing.");
    }

    try {
      final File file = File(imagePath);
      final bytes = await file.readAsBytes();
      final String imageBase64 = base64Encode(bytes);

      final HttpsCallable callable =
          FirebaseFunctions.instanceFor(region: 'europe-west1')
              .httpsCallable('uploadPhotoLimit');

      final HttpsCallableResult result = await callable.call({
        'imageBase64': imageBase64,
        'title': title,
        'description': description,
        'postType': postType,
      });

      final data = result.data;
      if (data == null || data['postId'] == null) {
        throw Exception("Erreur de la Cloud Function : postId manquant.");
      }
      return data['postId'] as String;
    } catch (error) {
      throw Exception("Erreur lors de la publication du post: $error");
    }
  }
}

客户端报错日志

I/flutter ( 6354): Erreur lors de la publication du post: Exception: Erreur lors de la publication du post: [firebase_functions/unauthenticated] UNAUTHENTICATED
I/flutter ( 6354): 
I/flutter ( 6354): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:652:7)
I/flutter ( 6354): #1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:370:18)
I/flutter ( 6354): <asynchronous suspension>
I/flutter ( 6354): #2      MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:22:24)
I/flutter ( 6354): <asynchronous suspension>
I/flutter ( 6354): #3      HttpsCallable.call (package:cloud_functions/src/https_callable.dart:49:37)
I/flutter ( 6354): <asynchronous suspension>
I/flutter ( 6354): #4      FirebasePublicationRepository.publishPost (package:coursios/blocs/publication/firebase_publication_repository.dart:46:42)
I/flutter ( 6354): <asynchronous suspension>
I/flutter ( 6354): #5      PublicationBloc._onPublishPost (package:coursios/blocs/publication/publication_bloc.dart:49:22)
I/flutter ( 6354): <asynchronous suspension>
I/flutter ( 6354): #6      Bloc.on.<anonymous closure>.handleEvent (package:bloc/src/bloc.dart:226:13)
I/flutter ( 6354): <asynchronous suspension>
I/flutter ( 6354): 
I/flutter ( 6354): #0      FirebasePublicationRepository.publishPost (package:coursios/blocs/publication/firebase_publication_repository.dart:60:7)
I/flutter ( 6354): <asynchronous suspension>
I/flutter ( 6354): #1      PublicationBloc._onPublishPost (package:coursios/blocs/publication/publication_bloc.dart:49:22)
I/flutter ( 6354): <asynchronous suspension>
I/flutter ( 6354): #2      Bloc.on.<anonymous closure>.handleEvent (package:bloc/src/bloc.dart:226:13)
I/flutter ( 6354): <asynchronous suspension>

Google Cloud日志提示

The request was not authorized to invoke this service. Additional troubleshooting documentation can be found at: [相关文档链接]


解决方案

1. 确认App Check与Cloud Functions的绑定配置

  • 进入Firebase控制台,找到目标Cloud Function,检查是否已开启App Check保护。
  • 验证App Check的提供者(如SafetyNet、App Attest)配置是否正确,确保客户端获取的token在有效期内且签名合法。

2. 修正权限配置细节

  • 若使用第二代Cloud Functions(基于Cloud Run),需同时配置Cloud Run服务的权限:
    1. 打开Google Cloud控制台,找到函数对应的Cloud Run服务。
    2. 进入「权限」标签,为allAuthenticatedUsers授予「Cloud Run Invoker」角色。
  • 确认Cloud Functions本身的权限配置:为allAuthenticatedUsers授予「Cloud Functions Invoker」角色,避免仅配置Cloud Run而遗漏函数层面的权限。

3. 确保客户端认证信息正确传递

  • 虽然HttpsCallable默认会自动携带Auth和App Check信息,可手动显式传递App Check token排查问题:
    final HttpsCallable callable = FirebaseFunctions.instanceFor(region: 'europe-west1')
        .httpsCallable('uploadPhotoLimit', options: HttpsCallableOptions(
      headers: {
        'X-Firebase-AppCheck': appCheckToken!,
      },
    ));
    
  • 验证用户Auth token有效性:调用user.getIdToken()确认能正常获取有效token,排除Auth状态异常导致的认证失败。

4. 检查函数内部的验证逻辑

  • 若函数中有自定义的App Check/Auth验证代码,确认逻辑无错误:
    const appCheck = require('firebase-admin').appCheck();
    exports.uploadPhotoLimit = async (req, res) => {
      const appCheckToken = req.headers['x-firebase-appcheck'];
      if (!appCheckToken) {
        return res.status(401).send('Unauthorized');
      }
      try {
        await appCheck.verifyToken(appCheckToken);
      } catch (err) {
        return res.status(401).send('Unauthorized');
      }
      // 后续业务逻辑
    };
    
    排查是否存在token过期、签名验证失败等问题。

5. 验证服务账号权限

  • 确认Firebase App Check的服务账号拥有验证token的权限,避免因账号权限不足导致验证失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:33:15