- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我一直在使用 FirebaseAuth 登录用户,并注意到 FirebaseUser 的 getToken 方法返回的 ID token 与 FCM FirebaseInstanceIdService 不同。
FirebaseAuth ID token 和 FCM 实例 ID onTokenRefresh 返回的 token 之间到底有什么区别? Instance ID token 和 ID token 的命名相似,因此让我感到有些困惑。
根据我的观察,通过 FirebaseUser 对象上的 getIdToken
方法获得的 FirebaseAuth token 将在一小时后过期。
getIdToken(boolean forceRefresh)
例如 token 是...
01-18 17:20:08.904 15947-15947/? D/FragmentCreate: Token found without force refresh from a single thread eyJhbGciOiJSUzI1NiIsImtpZCI6ImExNTAxNjY5NTNiYTFhMjBjY2FhOTdmOTM4M2NiMDg3OTYyODBkZDcifQ.eyJpc3MiOiJodHR....JTXpA
我观察到将 forceRefresh 设置为 true 会立即更改 token 。
例如。
01-18 17:22:16.990 15947-15947/? D/FragmentCreate: Token found single thread after force refresh eyJhbGciOiJSUzI1NiIsImtpZCI6ImExNTAxNjY5NTNiYTFhMjBjY2FhOTdmOTM4M2NiMDg3OTYyODBkZDcifQ.eyJpc3MiOiJod.......xQCA
现在,当我在最后一次显示的强制刷新一小时后调用 getIdToken(false) 时, token 确实发生了变化,因为它已经过期,并且通过深入研究 firebase 代码,我可以看到一些像 isValid() 这样的检查,我我猜测会检查 token 过期并刷新它,即使强制刷新为假也是如此。
为了让事情变得有趣,我在 token 过期后不久从两个线程同时调用了 getIdToken
(false) 来查看两者是否打印不同的 token ,因为两者都会看到 token 在同时,因此两者都应该尝试刷新 token
例如。
01-18 18:25:29.479 29849-29849/com.foodiniq.waitlist.katana D/FragmentCreate: Token found from thread1 after expiry eyJhbGciOiJSUzI1NiIsImtpZCI6ImExNTAxNjY5NTNiYTFhMjBjY2FhOTdmOTM4M2NiMDg3OTYyODBkZDcifQ.eyJpc3MiOiJod........GpdbA
01-18 18:25:30.071 29849-29849/com.foodiniq.waitlist.katana D/FragmentCreate: Token found from thread1 after expiry eyJhbGciOiJSUzI1NiIsImtpZCI6ImExNTAxNjY5NTNiYTFhMjBjY2FhOTdmOTM4M2NiMDg3OTYyODBkZDcifQ.eyJpc3MiOiJod........GpdbA
令我惊讶的是, token 确实如我所料刷新了,但它们都给出了相同的结果。这种暗示用于在内部获取 token 的方法可能是同步的,并且至少在从两个不同线程将 force refresh 设置为 false 调用时会返回相同的结果。对于 forceRefresh 设置为 true 也显示了类似的结果,同时线程打印具有相同值的新 token
我假设 getIdToken(false) 方法是线程安全的,并且在同时调用时在所有线程中总是只返回相同的值,这是否正确?此行为是否与 getIdToken(true) 不同?
P.S 用于在不从两个线程刷新的情况下获取 token 的代码是
Thread testThread1 = new Thread(new Runnable() {
@Override
public void run() {
if(FirebaseAuth.getInstance().getCurrentUser()!=null){
FirebaseAuth.getInstance().getCurrentUser().getIdToken(false).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
@Override
public void onComplete(@NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
Log.d("FragmentCreate","Token found from thread1 after expiry "+task.getResult().getToken());
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("FragmentCreate","Token failed from main thread single "+e.toString());
}
});
}
}
});
Thread testThread2 = new Thread(new Runnable() {
@Override
public void run() {
if(FirebaseAuth.getInstance().getCurrentUser()!=null){
FirebaseAuth.getInstance().getCurrentUser().getIdToken(false).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
@Override
public void onComplete(@NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
Log.d("FragmentCreate","Token found from thread2 after expiry "+task.getResult().getToken());
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("FragmentCreate","Token failed from main thread single "+e.toString());
}
});
}
}
});
testThread1.start();
testThread2.start();
单线程强制刷新调用token的方法是:
if(FirebaseAuth.getInstance().getCurrentUser()!=null){
FirebaseAuth.getInstance().getCurrentUser().getIdToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
@Override
public void onComplete(@NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
Log.d("FragmentCreate","Token found single thread after force refresh "+task.getResult().getToken());
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("FragmentCreate","Token failed from main thread single "+e.toString());
}
});
}
由于以下原因,我想要一个线程安全的实现:
每次启动应用程序时,我都会在不强制刷新的情况下获取 token 。并在所有后续请求中使用此 token 。(因此可能存在此 token 可能已过期的时间点,但用户保持应用程序运行一个小时的情况不太可能)
正如您所说,我在后端所做的就是验证 id token 。这里可能存在 token 可能已过期的点。所以我发送了一个响应代码,告诉客户端手动刷新 token 。现在这是在后端的所有 Servlet 上完成的,因此许多 Servlet 可以同时返回过期的响应代码。在这个响应中,我从任何获得响应代码的线程刷新客户端上的 token ,从而导致许多不同的线程调用客户端上的刷新方法。我基本上担心这可能是 token 刷新的配额
最佳答案
Firebase ID token 和 FCM token 是两个完全不同的东西:第一个是身份验证 token ,需要在您的后端服务器上验证请求,后者是唯一标识应用程序安装的实例,知道发送给谁正确的信息。还要考虑 Firebase 用户身份验证 ID - 它是线程安全的,并且是特定用户帐户的唯一 ID。
来自官方doc
Verify ID Tokens
If your Firebase client app communicates with a custom backend server, you might need to identify the currently signed-in user on that server. To do so securely, after a successful sign-in, send the user's ID token to your server using HTTPS. Then, on the server, verify the integrity and authenticity of the ID token and retrieve the uid from it. You can use the uid transmitted in this way to securely identify the currently signed-in user on your server.
同时 ( from official doc ):
Access the device registration token
On initial startup of your app, the FCM SDK generates a registration token for the client app instance. If you want to target single devices or create device groups, you'll need to access this token by extending FirebaseInstanceIdService.This section describes how to retrieve the token and how to monitor changes to the token. Because the token could be rotated after initial startup, you are strongly recommended to retrieve the latest updated registration token.
The registration token may change when:
- The app deletes Instance ID
- The app is restored on a new device
- The user uninstalls/reinstall the app
- The user clears app data.
因此,重点似乎有点偏离:为什么要拥有线程安全且唯一的身份验证 token ?在您的后端服务器上,您可以通过调用适当的函数(例如 Node.js 代码)简单地获取用户的 uid
:
admin.auth().verifyIdToken(idToken)
.then(function(decodedToken) {
var uid = decodedToken.uid;
// ...
}).catch(function(error) {
// Handle error
});
如果这些信息改变了对代码中发生的事情的理解,请随时详细说明/改进问题。
关于android - 什么是 FirebaseAuth ID token 及其线程安全的 getIdToken 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48322473/
我正在使用来自 javascript 客户端的 Firebase 身份验证进行测试,我正在尝试使用 retrieve id tokens on clients documentation 检索 idT
我正在使用 redux-saga和 redux-saga-firebase图书馆整合firebase使用 redux-sagas。问题是当我登录用户时,例如使用 signInWithEmailAndP
嘿,我正在使用 Firebase 身份验证并启用了 Google 登录 功能。Google 登录运行良好,我获得了所有信息。但是当我想将用户保存在 Firebase 用户列表中时,getIdToken
我正在开发一个 React Native 项目并使用 Firebase。 我试图让用户在验证其电子邮件地址后登录。我向用户发送一封注册电子邮件,用户单击验证链接来验证自己,然后应该能够登录。我当前的代
所以情况如下: 1) 用户已登录。最后生成的 token 是不久前生成的,并且已过期。即使没有,问题也不会出现。 2) 安装了应用程序更新。 (不是 android studio 即时运行的东西,实际
我不明白: FirebaseAuth.getInstance().currentUser.getIdToken(true).addOnSuccessListener { Log.d("tag"
因此,我在学习 Firebase/React 教程 (https://www.youtube.com/watch?v=m_u6P5k0vP0&t=2656s) 时遇到了问题。我在 auth 部分尝试设
我有一个 angularfire 身份验证服务,它工作得非常好——除了它不会刷新 token 。 我的刷新代码: firebase.auth().currentUser.getIdToken(true
我正在尝试使用 获取用户 token import { auth, database } from "firebase"; await token = await auth().currentUser
我正在使用 Firebase Auth 进行登录的 Next.js WEB/Node 应用上调试 session 超时问题。我正在利用自定义 token 来实现精细的 Firestore 安全规则。在
这是总是出错的行 String sess = "workid_token=" + AppHelper.getCurrSession().getIdToken().getJWTToken
我现在正在处理 firebase 身份验证,我正在关注这个 Firebase 文档。 访问https://firebase.google.com/docs/auth/admin/manage-cook
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我目前正在开发一个 Next.js (React) 项目,我使用 Firebase Auth 进行身份验证。我使用它连接到 REST API 后端,该后端接收 Firebase 提供的用户 token
我使用 this 在我的 firebase 项目上实现了 cookie session 关联。 我正在尝试获取 idToken在客户端将其发送到服务器端。 这是我在客户端使用的代码: $(functi
我在 Swift 中完成了以下操作: let currentUser = Auth.auth().currentUser currentUser?.getTokenForcingRefresh(tru
我一直在使用 FirebaseAuth 登录用户,并注意到 FirebaseUser 的 getToken 方法返回的 ID token 与 FCM FirebaseInstanceIdService
通过将 false 传递给 Auth.auth().currentUser?.getIDTokenForcingRefresh,该函数执行与 getIDToken 相同的操作,除了如果当前 token
如何在 firebase 版本 9 中使用 getIdToken() 身份验证方法? 在版本 8 中它是这样工作的 import firebase from "firebase"; const tok
我在 Angular 8 中使用 firebase 来验证前端和后端的用户。要在后端验证用户身份,我需要发送用户 ID token 。 我正在使用 firebase getIdToken 来获取 to
我是一名优秀的程序员,十分优秀!