首页 > 解决方案 > 如何格式化自定义令牌以进行 Firestore 身份验证?

问题描述

我使用以下方法登录 Google -

override fun onClick(view: View?) {
        when (view?.id) {
           ...


            R.id.google_login -> {
                val signInIntent: Intent = googleSignInClient.signInIntent
                startActivityForResult(signInIntent, GOOGLE_LOGIN_REQUEST_CODE)
            }
        }
    }



override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode != Activity.RESULT_OK || requestCode != GOOGLE_LOGIN_REQUEST_CODE) return
        val task: Task<GoogleSignInAccount> = GoogleSignIn.getSignedInAccountFromIntent(data)
        val account = task.getResult(ApiException::class.java)
        saveAccountData(account)
    }

    private fun saveAccountData(account: GoogleSignInAccount?) {
        if (account == null) {
            Toast.makeText(requireContext(), getString(R.string.login_fragment_null_account_error), Toast.LENGTH_SHORT).show()
            return
        }
        if (account.email == null) {
            Toast.makeText(requireContext(), getString(R.string.login_fragment_selected_account_has_no_email_error), Toast.LENGTH_LONG).show()
            return
        }
        // This method saves the data in my Firestore DB 
        viewmodel.registerUser(account).observeOnce(requireActivity(), Observer { error ->
            error?.let { message ->
                Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
                return@Observer
            }

            saveAccountToPrefs(account)

            navController.navigate(LoginFragmentDirections.actionLoginFragmentToTermsAndConditionsFragment(account.givenName!!))
        })
    }

private fun saveAccountToPrefs(account: GoogleSignInAccount) {
        profileSharedPrefs.edit {
            putString(USER_REGISTERED_ID, account.email)
            putString(USER_DISPLAY_NAME, account.displayName)
            putString(USER_TOKEN, account.id)
            putBoolean(DID_USER_REGISTER, true)
        }
    }

问题是,我的数据库有以下错误规则 -

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
    
      allow read, write: if true
    }
  }
}

我想添加简单的身份验证,如下所示 -

// Allow read/write access on all documents to any user signed in to the application
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

因此,当我在使用 ID(这是用户的电子邮件)时尝试像这里一样配置自定义令牌时,我总是会收到错误消息 -

private fun authAndNavigate(directions : NavDirections) {
        auth.signInWithCustomToken(profileSharedPrefs.getString(USER_TOKEN, "")!!)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Toast.makeText(requireContext(), auth.currentUser.toString(), Toast.LENGTH_LONG).show()
                    navController.navigate(directions)
                } else {
                    Toast.makeText(requireContext(), "Authentication failed, please restart app", Toast.LENGTH_LONG).show()
                    return@addOnCompleteListener
                }
            }
            .addOnFailureListener { exception ->
                exception.localizedMessage?.let { message ->
                    Toast.makeText(requireContext(), message, Toast.LENGTH_LONG).show()
                }
            }
    }

我得到的错误是 -

自定义令牌格式不正确。请检查文档。[无效的断言格式。需要 3 个点分隔的段。]

我找不到任何示例来说明如何以一种首先有效且不会引发错误然后使用我想在项目中实施的规则的方式实际格式化我的 ID(这是一封电子邮件)。

标签: androidkotlingoogle-cloud-firestorefirebase-authenticationaccess-token

解决方案


您从 Google 登录中获得的是 OAuth 凭据,您可以使用它来使用 Firebase 登录,方法是将这些凭据传递给,如本文档中关于使用 Google 身份验证凭据登录 FirebasesignInWithCredential中的步骤 4 所示。

您的代码调用signInWithCustomToken,它期望自定义 JWT 由您在自己的受信任环境中运行的代码铸造,如铸造自定义令牌的文档中所示。

虽然这两种类型的令牌都可用于通过 Firebase 进行身份验证,但您不能在 API 调用中互换它们。


推荐阅读