【问题标题】:How can I differentiate between authenticated users?如何区分经过身份验证的用户?
【发布时间】:2020-05-21 12:43:11
【问题描述】:

我正在构建一个同时拥有商家和客户的应用。商家提供服务,客户可以向商家预订服务。

它们都已通过 Firebase 进行身份验证,并且位于您可以在 Firebase 控制台上找到的身份验证列表中。

在注册时,商家的信息会转到一个名为“商家”的集合中。客户继续收集称为“用户”的集合。

这就是我创建“用户”文档的方式

async createUserProfileDocument(user, additionalData) {
    if (!user) return
    const userRef = this.firestore.doc(`users/${user.uid}`)
    const snapshot = await userRef.get()
    if (!snapshot.exists) {
      const { displayName, email, photoURL, providerData } = user
      const createdAt = moment().format('MMMM Do YYYY, h:mm:ss a')
      try {
        await userRef.set({
          displayName,
          email,
          photoURL,
          createdAt,
          providerData: providerData[0].providerId, //provider: 'google.com', 'password'
          ...additionalData,
        })
      } catch (error) {
        console.error('error creating user: ', error)
      }
    }
    return this.getUserDocument(user.uid)
  }

  async getUserDocument(uid) {
    if (!uid) return null
    try {
      const userDocument = await this.firestore.collection('users').doc(uid).get()
      return { uid, ...userDocument.data() }
    } catch (error) {
      console.error('error getting user document: ', error)
    }
  }

这就是“用户”的注册方式

export const Register = () => {
  const history = useHistory()

  async function writeToFirebase(email, password, values) { //function is called below
    try {
      const { user } = await firebaseService.auth.createUserWithEmailAndPassword(email, password)
      firebaseService.createUserProfileDocument(user, values)
    } catch (error) {
      console.error('error: ', error)
    }
  }

  //Formik's onSubmit to submit a form
  function onSubmit(values, { setSubmitting }) {
    values.displayName = values.user.name
    writeToFirebase(values.user.email, values.user.password, values) //function call
  }

这就是“商家”的注册方式。他们使用电子邮件 + 密码进行注册,他们的信息从一个表格转到一个名为“企业”的集合

firebaseService.auth.createUserWithEmailAndPassword(values.user.email, values.user.password)
await firebaseService.firestore.collection('businesses').add(values) //values from a form

在这里我希望能够区分“用户”和“商家”,以便我可以使用“商家”数据编写一些逻辑。到目前为止,它只适用于“用户”

useEffect(() => {
    firebaseService.auth.onAuthStateChanged(async function (userAuth) {
      if (userAuth) {
         //**how can I find out if this userAuth is a 'merchant' (business) or 'user' (client)
        const user = await firebaseService.createUserProfileDocument(userAuth)
        setUsername(user.displayName)
        //if (userAuth IS A MERCHANT) setUserIsMerchant(true)   **what I'd like to be able to do
      } else {
        console.log('no one signed in')
      }
    })
  }, [])

【问题讨论】:

    标签: javascript firebase google-cloud-firestore firebase-authentication


    【解决方案1】:

    实施基于角色的访问控制系统的推荐方法是使用Custom Claims

    您将自定义声明(和 Firebase 身份验证)与 Firebase Security Rules 结合使用。如上述文档中所述:

    Firebase Admin SDK 支持在用户上定义自定义属性 帐户。这提供了实现各种访问的能力 Firebase 中的控制策略,包括基于角色的访问控制 应用。 这些自定义属性可以为用户提供不同级别的 访问(角色),在应用程序的安全规则中强制执行

    一旦您为用户分配了与其用户角色相对应的自定义声明(例如商家或客户声明),您将能够:

    1. 根据声明调整您的安全规则;
    2. 在前端获取声明并采取相应措施(例如,路由到特定应用屏幕/页面、显示特定 UI 元素等...)

    更准确地说,如 doc 中所述,您可以执行以下操作:

    useEffect(() => {
        firebaseService.auth.onAuthStateChanged(userAuth => {
          if (userAuth) {
    
             userAuth.getIdTokenResult()
             .then((idTokenResult) => {
                 // Confirm the user is a Merchant or a Client
                 if (!!idTokenResult.claims.merchant) {
                     // Do what needs to be done for merchants
                 } else if (!!idTokenResult.claims.client) {
                     // Do what needs to be done for clients
                 }
          } else {
            console.log('no one signed in')
          }
        })
      }, [])
    

    您可能会对article 感兴趣,它介绍了“如何创建管理模块以管理用户访问权限和角色”(免责声明,我是作者)

    【讨论】:

    • 不幸的是,您的代码没有加载到文章中。我稍后再试。通过阅读您提供的文档,我得到了另一个问题:除了 Firebase + React,我还需要做一些工作吗?使用 Node 后端?
    • “文章中没有加载您的代码”->您能否提供更多详细信息。如果您遇到问题,请在文章本身添加评论/问题。 “除了 Firebase + React 之外,我还需要做一些工作吗?”-> 如文章“应通过 Firebase Admin SDK 从特权服务器环境设置自定义声明”中所述。对于“特权服务器环境”,文档意味着您完全控制的服务器或运行后端代码的 Firebase 项目中的云函数(并且您也可以控制,因为它在您自己的项目中)。”
    • Cloud Functions 与 Forebase 完全集成,是“一个 无服务器 框架,可让您自动运行后端代码以响应由 Firebase 功能触发的事件”。所以,不需要额外的服务器
    猜你喜欢
    • 2014-07-13
    • 1970-01-01
    • 2017-09-11
    • 2020-11-15
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    相关资源
    最近更新 更多