我有一个登录页面,可以使用以下方式对用户进行身份验证
signInWithEmailAndPassword()
使用 Javascript 客户端 SDK。
如果登录成功,用户将被重定向(连同 idToken)到会员页面。
在服务器端(使用firebase admin SDK的nodejs),会员页面检查idToken的有效性,如果有效,它会从Firebase获取用户特定的数据并将其显示在网页上。在会员页面上,有大量数据可供查看/编辑/删除等。因此,用户可能会在该页面上花费一个多小时也不是不可想象的。
我的问题是,我找不到方法来检测 idToken 是否已过期。理想情况下,我想刷新并获取新的 idToken。那可能吗?如果这是不可能的,我想在 idToken 过期时将用户重定向到登录页面。
但我不知道如何实现其中任何一个。看起来 idToken 过期时不会触发
onAuthStateChanged
和 onIdTokenChanged
。而且我无法像firebase.auth().currentUser.getIdToken(true)
那样对 idToken 进行强制刷新。因为在会员页面,firebase.auth().currentUser
返回null。
对于如何处理这种情况有什么建议吗?
谢谢。
使用 Firebase Node.js 管理 SDK,您可以在调用
verifyIdToken()
时通过将 checkRevoked
参数设置为 true
来检查已撤销或过期的 ID 令牌。
verifyIdToken(idToken: string, checkRevoked?: boolean): Promise<DecodedIdToken>
已检查已撤销:布尔值
是否检查ID令牌是否被撤销。这需要向 Firebase Auth 后端发出额外请求来检查相应用户的时间。如果未指定,则不应用此附加检查。tokensValidAfterTime
admin.auth().verifyIdToken(idToken, true)
.then(function(decodedToken) {
let uid = decodedToken.uid;
// ...
}).catch(function(error) {
// Handle error for expired ID token
});
或者,可以在客户端上检查 ID 令牌有效负载声明。有关如何使用第三方 JWT 库验证 ID 令牌的文档显示了有效负载声明。
过期时间:必须是将来的时间。自 UNIX 纪元以来,时间以秒为单位进行测量。exp
jwt.io 引用支持客户端令牌验证的库。
您可以使用
jwt-decode
库:
import { jwtDecode } from 'jwt-decode';
async function getValidToken() {
let token = await auth.currentUser?.getIdToken();
if(!token) {
return null;
}
const currentTime = new Date().getTime() / 1000;
const expiry = jwtDecode(token).exp ?? 0;
const expired = currentTime > expiry;
if(expired) {
try {
token = await auth.currentUser?.getIdToken(true);
} catch (e) {
console.error('Error refreshing token', e);
}
}
return token;
}