Mik*_*ont 4 firebase firebase-authentication server-side-rendering
我们在工作中的 Next.js 应用中使用 Firebase。我对两者都是新手,但尽了最大努力阅读两者。我的问题更多的是 Firebase,而不是 Next.js。这是上下文:
在客户端应用程序中,我对 API 进行了一些调用,并在标头中传递 JWT(ID 令牌)Authorization。API 调用admin.auth().verifyIdToken以检查 ID 令牌是否足够新鲜。这工作正常,因为我或多或少保证 ID 令牌会定期刷新(通过使用onIDTokenChanged(doc link)
现在我希望能够在服务器端渲染我的应用程序页面。为此,我将 ID 令牌存储在服务器可读的 cookie 中。但从现在开始,我不能保证下次用户通过整页加载来加载应用程序时 ID 令牌足够新鲜。
我找不到与onIDTokenChanged.
这篇博文提到了一个用于刷新令牌的google API 端点。我可以从服务器上访问它并给它一个刷新令牌,但感觉就像我完全走出了 Firebase 领域,我担心维护临时系统将成为一种负担。
所以我的问题是,人们通常如何协调 Firebase 身份验证与 SSR?我错过了什么吗?
谢谢你!
小智 6
我最近也遇到了同样的问题,我自己解决了。我创建了一个非常简单的页面,负责强制 firebase 令牌刷新,并将用户重定向回请求的页面。是这样的:
exp从 cookie 中提取令牌值后检查它(如果您在该服务器上使用 firebase-admin,它可能会在验证后告诉您错误)// Could be a handler like this
const handleTokenCookie = (context) => {
try {
const token = parseTokenFromCookie(context.req.headers.cookie)
await verifyToken(token)
} catch (err) {
if (err.name === 'TokenExpired') {
// If expired, user will be redirected to /refresh page, which will force a client-side
// token refresh, and then redirect user back to the desired page
const encodedPath = encodeURIComponent(context.req.url)
context.res.writeHead(302, {
// Note that encoding avoids URI problems, and `req.url` will also
// keep any query params intact
Location: `/refresh?redirect=${encodedPath}`
})
context.res.end()
} else {
// Other authorization errors...
}
}
}
Run Code Online (Sandbox Code Playgroud)
该处理程序可以在 /pages 上使用,如下所示
// /pages/any-page.js
export async function getServerSideProps (context) {
const token = await handleTokenCookie(context)
if (!token) {
// Token is invalid! User is being redirected to /refresh page
return {}
}
// Your code...
}
Run Code Online (Sandbox Code Playgroud)
/refresh页面,负责在客户端强制刷新 firebase 令牌,并且在更新令牌和 cookie 后,它应该将用户重定向回所需的页面。// /pages/refresh.js
const Refresh = () => {
// This hook is something like https://github.com/vercel/next.js/blob/canary/examples/with-firebase-authentication/utils/auth/useUser.js
const { user } = useUser()
React.useEffect(function forceTokenRefresh () {
// You should also handle the case where currentUser is still being loaded
currentUser
.getIdToken(true) // true will force token refresh
.then(() => {
// Updates user cookie
setUserCookie(currentUser)
// Redirect back to where it was
const decodedPath = window.decodeURIComponent(Router.query.redirect)
Router.replace(decodedPath)
})
.catch(() => {
// If any error happens on refresh, redirect to home
Router.replace('/')
})
}, [currentUser])
return (
// Show a simple loading while refreshing token?
<LoadingComponent />
)
}
export default Refresh
Run Code Online (Sandbox Code Playgroud)
当然,如果令牌过期,它会延迟用户的第一次请求,但它可以确保令牌有效,而不会强制用户再次登录。
| 归档时间: |
|
| 查看次数: |
1861 次 |
| 最近记录: |