我是一名新手(大约 6 个月),正在 Android (Java) 上创建一个使用 FireBase Auth 和 Google Sign In 的应用程序。 (现在只有几天的 NodeJS 曝光)换句话说,我的最终用户使用 Google 帐户登录。这部分(我认为)到目前为止效果很好。我在应用程序中大量使用 Firestore 数据库来完成很多事情。

现在我想将(可调用)云函数与 HTTP 触发器结合使用。 (以前从未做过这些)我现在正试图获得一个有效的概念证明。实际功能有效,我可以从我的应用程序触发它。

看来我无法弄清楚如何使该函数成为“私有(private)”;如“向云功能添加适当的成员”,这些成员有权调用该功能。

我通过尝试错误尝试了一些不同的方法,但首先让我展示一下我所拥有的。

这是云函数,我传入任意字符串作为测试,效果很好:(只要“allUsers”具有调用该函数的角色/权限;换句话说,当该函数是公共(public)的时。

 
exports.createTest = functions.https.onCall((data, context) => { 
 
const text = data.text; 
 
const uid = context.auth.uid; 
const name = context.auth.token.name || null; 
const email = context.auth.token.email || null; 
 
console.log('UID: ', uid); 
console.log('Name: ', name); 
console.log('Email: ', email); 
console.log('Message: ', text); 
 
 
 
}); 

上面的函数在我的 Android/Java 代码中被触发,如下所示:(我认为该代码来自 Google Doc/Sample/Example

    private FirebaseFunctions mFunctions; 
 
 
    ... 
 
    private void testing() { 
 
 
        mFunctions = FirebaseFunctions.getInstance(); 
 
        Log.e(LOG_TAG, "Testing executed!"); 
 
        String testMessage = "Hello Hello Testing 123 Mic Check"; 
 
 
        createTest(testMessage) 
                .addOnCompleteListener(new OnCompleteListener<String>() { 
                    @Override 
                    public void onComplete(@NonNull Task<String> task) { 
                        if (!task.isSuccessful()) { 
                            Exception e = task.getException(); 
                            if (e instanceof FirebaseFunctionsException) { 
                                FirebaseFunctionsException ffe = (FirebaseFunctionsException) e; 
                                FirebaseFunctionsException.Code code = ffe.getCode(); 
                                Object details = ffe.getDetails(); 
 
                                Log.e(LOG_TAG, "FFE: " + ffe.getMessage() ); 
                                Log.e(LOG_TAG, "Code: " + code); 
                                Log.e(LOG_TAG, "Details:" + details); 
                            } 
 
                            // ... 
                        } 
 
                        // ... 
                    } 
                }); 
 
    } 
 
    private Task<String> createTest(String text) { 
        // Create the arguments to the callable function. 
        Map<String, Object> data = new HashMap<>(); 
        data.put("text", text); 
        data.put("push", true); 
 
        return mFunctions 
                .getHttpsCallable("createTest") //this is the function name 
                .call(data) 
                .continueWith(new Continuation<HttpsCallableResult, String>() { 
                    @Override 
                    public String then(@NonNull Task<HttpsCallableResult> task) throws Exception { 
                        // This continuation runs on either success or failure, but if the task 
                        // has failed then getResult() will throw an Exception which will be 
                        // propagated down. 
                        String result = (String) task.getResult().getData(); 
 
                        if (result != null) { 
                            Log.e(LOG_TAG, "Result: " + result); 
                        } 
                        return result; 
                    } 
                }); 
    } 
 

只有当我添加了“allUsers”并添加了“调用云功能”的角色/权限时,我才能正常工作。我对 HTTP 请求等的理解非常有限,这并没有让事情变得更容易。

我尝试使用“allAuthenticatedUsers”选项,我认为这可以解决问题,因为我实际上是通过 Firebase/Google 登录对应用中的用户进行身份验证。此云功能仅适用于 a) 经过身份验证的用户或 b) 特定域的用户。 (我有一个域,比如说@testorganization.com)或者如果我可以识别我的特定应用程序(API key ?),那么这也可以。

当我添加一个具有调用该函数的角色的成员“allAuthenticatedUsers”(并删除“allUsers”)时,什么也没有发生。我也尝试添加整个域,但这行不通。(duh)还尝试添加我的服务帐户(此时反复试验),但似乎不起作用。

在我的 Node JS 代码中,我实际上收到了经过身份验证的用户的 UID,因此似乎已经交换了某种用户身份验证信息。

有了这些知识,我可以(成功地尝试过这个)获取 UID 并对照我的数据库进行交叉检查并以这种方式验证用户,但似乎没有必要,我应该能够使权限发挥作用。 (完全锁定该功能)另外,这花了很长时间才完成此交叉检查。或者这是相当标准的程序?

像这样-->

const usersRef =  admin.firestore().collection('users').doc(uid) 
 
usersRef.get() 
  .then((docSnapshot) => { 
    if (docSnapshot.exists) { 
      usersRef.onSnapshot((doc) => { 
       console.log('User Type logged in: ', doc.data().userCategory) 
       console.log('User Title: ', doc.data().userTitle) 
      }); 
    } else { 
      console.log('User does not exist') 
    } 
 
}); 
 

编辑:

因此,虽然没有弄清楚如何完全关闭该功能,但我确实发现,我可以像这样简单地检查身份验证,而不是交叉检查我的用户:

if (context.auth){ 
  //user is auth'd 
} else { 
  //no auth 
} 
 

我想这会好一点。 (但从技术上来说仍然没有阻止对该功能的访问?!)

非常感谢您的帮助。非常感激。

编辑2:

这是我所指的云控制台区域(用于云功能角色/权限)的屏幕截图:

/image/BEQVt.jpg

请您参考如下方法:

使用可调用云函数,如果您想确保只有经过身份验证的用户才能触发其业务逻辑,您实际上不需要配置任何额外的“云函数角色/权限”,如问题底部所示。

默认情况下,使用可调用云函数,您将在可用时获得“请求中自动包含的 Firebase 身份验证和 FCM token ”,并且它将“自动反序列化请求正文并验证身份验证 token ”,如 doc 中所述。

因此您只需遵循 doc 并使用 context 参数即可。正如您在问题中提到的,您可以通过执行以下操作来检查用户是否经过身份验证:

if (context.auth) { 
  //... 
} 

如果您想验证用户电子邮件,您可以这样做:

exports.addMessage = functions.https.onCall((data, context) => { 
 
    const uid = context.auth.uid; 
    return admin.auth().getUser(uid) 
      .then(userRecord => { 
          const userEmail = userRecord.email; 
          //.... 
       }) 
       .catch(function(error) { 
           console.log('Error fetching user data:', error); 
          // Send back an error to the front end 
          // See https://firebase.google.com/docs/functions/callable#handle_errors 
       }); 
 
}); 

您将在文档中找到有关如何使用 Admin SDK here“与用户合作”的更多示例。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!