我是一名新手(大约 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:
这是我所指的云控制台区域(用于云功能角色/权限)的屏幕截图:
请您参考如下方法:
使用可调用云函数,如果您想确保只有经过身份验证的用户才能触发其业务逻辑,您实际上不需要配置任何额外的“云函数角色/权限”,如问题底部所示。
默认情况下,使用可调用云函数,您将在可用时获得“请求中自动包含的 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“与用户合作”的更多示例。