Firebase:如何在onCreate Firebase云函数中获取getAdditionalUserInfo

5

我正在尝试从SAML登录提供程序获取一些额外的数据。我可以在客户端看到这些数据,但我不知道如何在后端(firebase函数)中获取这些数据。

我在前端使用以下内容:

"firebase": "^9.8.2",
"firebase-functions": "^3.14.1",

还有这个在BE中

"firebase-admin": "^10.2.0",
"firebase-functions": "^3.21.2",

这是客户端获取数据的方法:

async myproviderSignIn() {
  const provider = new SAMLAuthProvider('saml.myprovider');
  const auth = getAuth();

  const userCredential = await signInWithPopup(auth, provider);
  const credential = SAMLAuthProvider.credentialFromResult(userCredential);

  if (!environment.production) {
    console.log('User:', userCredential, credential);
    console.log(
      'getAdditionalUserInfo:',
      getAdditionalUserInfo(userCredential)
    );
  }
}

以下是我期望的并由客户端的getAdditionalUserInfo记录下来的内容:

{
    "isNewUser": false,
    "providerId": "saml.myprovider",
    "profile": {
        "urn:schac:attribute-def:schacPersonalUniqueCode": "urn:schac:personalUniqueCode:nl:local:diy.myproviderconext.nl:studentid:123456",
        "urn:oid:1.3.6.1.4.1.25178.1.2.9": "diy.myproviderconext.nl",
        "urn:oid:1.3.6.1.4.1.25178.1.2.14": "urn:schac:personalUniqueCode:nl:local:diy.myproviderconext.nl:studentid:123456",
        "urn:oid:0.9.2342.19200300.100.1.3": "student1@diy.myproviderconext.nl",
        "urn:oid:1.3.6.1.4.1.5923.1.1.1.1": [
            "student",
            "employee",
            "staff",
            "member"
        ],
        "urn:mace:dir:attribute-def:eduPersonAffiliation": [
            "student",
            "employee",
            "staff",
            "member"
        ],
        "urn:mace:dir:attribute-def:sn": "One",
        "urn:mace:dir:attribute-def:givenName": "Student",
        "urn:oid:2.5.4.42": "Student",
        "urn:mace:dir:attribute-def:mail": "student1@diy.myproviderconext.nl",
        "urn:oid:2.5.4.4": "One",
        "urn:mace:terena.org:attribute-def:schacHomeOrganization": "diy.myproviderconext.nl"
    }
}

最后这是我的用户创建触发器的BE。 当Firebase认证中创建新用户时,它会创建一个用户的DB记录。我希望将上面显示的一些属性映射到DB中的用户记录中。

export const onCreate = functions.auth
  .user()
  .onCreate((user: UserRecord, context: EventContext) => {
    const timestamp = serverTimestamp();

    const dbUser: DbUser = {
      uid: user.uid,
      name: user.displayName || '',
      firstName: user.displayName || '',
      lastName: '',
      email: user.email,
      photoURL: user.photoURL,
      emailVerified: user.emailVerified,
      createdDate: timestamp,
      lastSeen: timestamp,
      providerData: JSON.parse(JSON.stringify(user.providerData)),
      userDump: JSON.parse(JSON.stringify(user)),
      contextDump: JSON.parse(JSON.stringify(context)),
    };

    // Get additional user data from the UserCredential
    // const additionalUserInfo = getAdditionalUserInfo(user); ???

    const result = getFirestore()
      .collection(constants.dbCollections.users)
      .doc(user.uid)
      .set(dbUser);

    return result;
  });

我如何在不依赖客户端的情况下,访问我的云函数中的这些附加属性?


您能否澄清一下,"additional means" 指的是您想显示哪些数据? - Salman Shaikh
1
我可能会把数据暂时存储在Firestore中,当触发器被触发时再检索它,虽然这不是理想的解决方案。 - omeanwell
@omeanwell 的意思是将其存储在 Firestore 中,而不依赖于客户端。 - Jonathan
我认为你的问题不够清晰,或者我觉得你误解了我的评论。 - omeanwell
1
@omeanwell,我不理解你的评论。我正在尝试以安全的方式从我的BE中获取SAML提供程序的属性。 - Jonathan
1个回答

0

你要解决的问题在这里有详细说明:

https://firebase.google.com/docs/auth/admin/custom-claims#node.js

您在下面描述的数据中,有一部分存储在auth.user中。

const dbUser: DbUser = {
  uid: user.uid,
  name: user.displayName || '',
  firstName: user.displayName || '',
  lastName: '',
  email: user.email,
  photoURL: user.photoURL,
  emailVerified: user.emailVerified,
  createdDate: timestamp,<-----------------------------------------------here
  lastSeen: timestamp,<--------------------------------------------------and here
  providerData: JSON.parse(JSON.stringify(user.providerData)),
  userDump: JSON.parse(JSON.stringify(user)),
  contextDump: JSON.parse(JSON.stringify(context)),
};

但是我标记为“here”的数据需要通过“自定义用户声明”创建,但它位于FireBaseAnalytics选项卡下,既不属于auth也不属于firestore,如果您坚持要从Firebase检索此数据。

But for this data :

  providerData: JSON.parse(JSON.stringify(user.providerData)),
  userDump: JSON.parse(JSON.stringify(user)),
  contextDump: JSON.parse(JSON.stringify(context)),

如果您坚持从 FireBase 获取数据,由于自定义声明的 1000 字节策略,您应该使用 FireStore 或 FirebaseRealTimeDatabase。

我希望我理解您的问题。但是,如果您使用这些属性,我相信会更好。

// Set admin privilege on the user corresponding to uid.

getAuth()
  .setCustomUserClaims(uid, { admin: true })
  .then(() => {
    // The new custom claims will propagate to the user's ID token the
    // next time a new one is issued.
  });

你可以使用.auth token检索它


我知道自定义声明,问题是我不知道如何在后端访问来自我的SAML提供程序的属性。 - Jonathan
请问您能否描述一下“如何获取授权令牌到后端”的过程。我向我的一个朋友询问了这个问题,他刚从SAML转移到OIDC。我们可能会想出一个解决方案。 - Ahmet Emre
不错的想法,我会研究一下 OIDC,看看是否可以通过这种方式实现。 - Jonathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接