如何为 Firestore 身份验证格式化自定义令牌?
How to format custom token for Firestore authentication?
我使用以下方法登录 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()
}
}
}
我得到的错误是-
The custom token format is incorrect. Please check the documentation. [ Invalid assertion format. 3 dot-separated segments required. ]
我找不到任何示例来说明如何实际格式化我的 ID(这是一封电子邮件)的方式首先可以工作并且不会引发错误,然后再使用我想在我的项目中实施的规则。
您从 Google sign-in 返回的是一个 OAuth 凭据,您可以通过将这些凭据传递给 signInWithCredential
来使用它登录 Firebase,如第 4 步中所示signing in with Firebase with Google auth credentials.
上的此文档
您的代码调用 signInWithCustomToken
,它需要一个自定义 JWT,由您 运行 在自己的可信环境中生成的代码生成,如 minting custom tokens 上的文档所示。
虽然这两种类型的令牌都可用于通过 Firebase 进行身份验证,但您不能在 API 调用中交换它们。
我使用以下方法登录 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()
}
}
}
我得到的错误是-
The custom token format is incorrect. Please check the documentation. [ Invalid assertion format. 3 dot-separated segments required. ]
我找不到任何示例来说明如何实际格式化我的 ID(这是一封电子邮件)的方式首先可以工作并且不会引发错误,然后再使用我想在我的项目中实施的规则。
您从 Google sign-in 返回的是一个 OAuth 凭据,您可以通过将这些凭据传递给 signInWithCredential
来使用它登录 Firebase,如第 4 步中所示signing in with Firebase with Google auth credentials.
您的代码调用 signInWithCustomToken
,它需要一个自定义 JWT,由您 运行 在自己的可信环境中生成的代码生成,如 minting custom tokens 上的文档所示。
虽然这两种类型的令牌都可用于通过 Firebase 进行身份验证,但您不能在 API 调用中交换它们。