Firebase用户的context.auth仍存在allAuthenticatedUsers保护的Google函数错误,并带有UNAUTHENTICATED [英] Firebase user's context.auth is present still allAuthenticatedUsers secured Google function error with UNAUTHENTICATED

查看:82
本文介绍了Firebase用户的context.auth仍存在allAuthenticatedUsers保护的Google函数错误,并带有UNAUTHENTICATED的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个简单的 cloud 函数:

I wrote a simple cloud function:

import * as functions from 'firebase-functions';

export const repeat = functions.https.onCall( function (data, context) {
    // Authentication user information is automatically added to the request.
    if (context.auth) {
        console.log(' context.auth is defined ');
        console.log(' uid is ' + context.auth.uid);
    } else {
        console.log(' context.auth undefine. ');
    }
        if (context.auth) {
            return {
                repeat_message: context.auth.uid + ' ' + data.message,
                repeat_count: data.count + 1,
            };
        } else {
            return {
                repeat_message: ' noUID ' + data.message,
                repeat_count: data.count + 1,
            };
        }    }
);

以及相应的Flutter Client应用:

And a corresponding Flutter Client app:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:cloud_functions/cloud_functions.dart';

final FirebaseAuth _fAuth = FirebaseAuth.instance;

final GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['email'], signInOption: SignInOption.standard);

FirebaseUser _firebaseUser;
GoogleSignInAccount _googleSignInAccount;

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        textTheme: TextTheme(
          caption: TextStyle(
              fontSize: 20.0
          ),
          body1: TextStyle(
              fontSize: 20.0
          ),
        ),
      ),
      title: 'calling function',
      debugShowCheckedModeBanner: false,
      home: LaunchScreen(),
    );
  }
}

class LaunchScreen extends StatefulWidget {
  @override
  _LaunchScreenState createState() {
   return _LaunchScreenState();
  }
} // LoggingOptions  to _LaunchScreenState

class _LaunchScreenState extends State<LaunchScreen> {
  String _response = 'no response';
  int _responseCount = 1;
  final HttpsCallable callable = CloudFunctions.instance.getHttpsCallable(functionName: 'repeat')
    ..timeout = const Duration(seconds: 90);

  Future<FirebaseUser> _handleSignIn() async {
    try {
      GoogleSignInAccount googleSignInAccount = await _googleSignIn.signIn();
      _googleSignInAccount = googleSignInAccount;

      GoogleSignInAuthentication authentication = await googleSignInAccount.authentication;

      final AuthCredential credential = GoogleAuthProvider.getCredential(
        accessToken: authentication.accessToken, idToken: authentication.idToken,
      );
      AuthResult authResult;
      authResult = await _fAuth.signInWithCredential( credential);

      _firebaseUser = authResult.user;
      setState(() {});
      return _firebaseUser;
    } catch (e) {
      print(e.toString());
    }
    return null;
  }

  Future<void> _handleSignOut() async {
    FirebaseAuth.instance.signOut();
    _googleSignIn.signOut();

    setState(() {
      _firebaseUser =null;
      _googleSignInAccount= null;
    });
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
        appBar: AppBar( title: const Text('Sample Code'),),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              MaterialButton(
                  child: const Text( 'Sign in with Google', style: TextStyle(fontSize: 16.0),),
                  onPressed: () {
                    _handleSignIn().then((user) {
                      // logggedIn
                      debugPrint('user ' + user.toString());
                    }
                        );
                  },
                  ),

                 MaterialButton(
                  child: const Text( 'Sign out with Google', style: TextStyle(fontSize: 16.0),),
                  onPressed: () {
                    _handleSignOut();
                  },
                ),

              Text( _firebaseUser != null ? _firebaseUser.uid : 'user logged off'),

              Text('FromServer $_responseCount: $_response'),
              MaterialButton(
                child: const Text('SEND REQUEST', style: TextStyle(fontSize: 18.0),),
                onPressed: () async {
                  try {
                    final HttpsCallableResult result = await callable.call(
                      <String, dynamic>{
                        'message': 'hello',
                        'count': _responseCount,
                      }
                      ,
                    );
                    print(result.data);
                    setState(() {
                      _response = result.data['repeat_message'];
                      _responseCount = result.data['repeat_count'];
                    });
                  } on CloudFunctionsException catch (e) {
                    print('caught Firebase functions exception');
                    print(e.code);
                    print(e.message);
                    print(e.details);
                  } catch (e) {
                    print('caught generic exception');
                    print(e);
                  }
                },
              ),
            ],
          ),
        ));
  }    }

,我在服务器日志和客户端中都可以看到Auth正确传递.

and I can see in both server logs and client side that Auth is passed correctly.

但是当我添加allAuthenticatedUsers并将allUsers删除到"Cloud Functions Invoker"角色时

But when I add allAuthenticatedUsers and remove allUsers to 'Cloud Functions Invoker' Role from the function, the App starts getting PlatformException with UNAUTHENTICATED code.

这是更改之前设置的外观:

Here is how setting looks before the change:

在添加allAuthenticatedUsers之后:

删除allUsers后:

然后,当Flutter调用该功能(用户登录时)时,Flutter出现错误,并显示

Then when Flutter invokes the function (when the user is logged in), Flutter errors with

PlatformException(functionsError,Cloud function failed with 例外.,{消息:未经授权,详细信息:null,代码: 未经授权})

PlatformException(functionsError, Cloud function failed with exception., {message: UNAUTHENTICATED, details: null, code: UNAUTHENTICATED})

仅当用户未登录时,它应该显示错误,但在两种情况下均会显示.

It should show an error only when the user is not logged in, but it is showing in either cases.

推荐答案

allAuthenticatedUsers的云配置与Firebase无关,它与可调用类型函数的身份验证无关. Firebase可调用函数与更改的配置分开处理自己的身份验证.如果您希望可调用对象正常工作,则应将其改回.

The cloud configuration for allAuthenticatedUsers is not in any way related to Firebase, and what it does for authentication for callable type functions. Firebase callable functions handle their own authentication separately from the configuration you changed. You should change it back if you want callables to work properly.

您删除的allUsers权限负责使您的功能(包括您的应用)对公众开放.删除该链接后,实际上删除了Internet上任何人都可以调用该功能的功能(这是可调用功能按设计运行所必需的).

The allUsers permission that you removed was responsible for making your function accessible to the public, including your app. When you removed that, you effectively removed the ability for anyone on the internet to be able to invoke the function (which is very much required for callable functions to operate as designed).

添加allAuthenticatedUsers时,您所做的只是要求使用Google服务帐户进行身份验证的呼叫者.同样,这与Firebase或Firebase身份验证无关.这是Google Cloud IAM概念.它不适用于可调用函数,因此您不应使用它.对我来说还不清楚,为什么您认为这是一个很好的配置.

When you added allAuthenticatedUsers, what you did was require only callers that authenticate themselves with a Google service account. Again, this is not related to Firebase or Firebase Auth. It's a Google Cloud IAM concept. It's not applicable for callable functions, so you shouldn't use it. It's not clear to me why you thought this was a good configuration to make.

如果您希望从应用程序正常调用Firebase可调用函数,则应保留默认的allUsers权限,并让Firebase SDK处理最终用户的身份验证.

If you want Firebase callable functions to be invoked normally from apps, you should leave the permission at the default allUsers, and let the Firebase SDK handle the authentication of the end user.

详细了解 Google云访问控制列表,以了解您正在更改的云配置.

Read more about Google Cloud access control lists to understand the cloud configurations that you were changing.

这篇关于Firebase用户的context.auth仍存在allAuthenticatedUsers保护的Google函数错误,并带有UNAUTHENTICATED的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆