Gatsby集成Auth0使用withAuthenticationRequired卡在Redirecting无法跳转登录
问题原因
- Auth0 SDK 初始化未完成就触发了高阶组件的鉴权逻辑。Gatsby 存在服务端渲染(SSR)和静态站点生成(SSG)阶段,这两个阶段无法执行浏览器端的 Auth0 初始化逻辑,
withAuthenticationRequired高阶组件在 Auth0 实例还处于加载状态时,会持续渲染onRedirecting传入的内容,不会触发跳转逻辑。 - Auth0Provider 挂载位置错误。如果 Auth0Provider 没有包裹到所有受保护页面的上层,或者没有在 Gatsby 全局根元素包裹函数中挂载,会导致页面路由切换时 Auth0 状态丢失,高阶组件无法拿到正确的登录状态触发跳转。
- 高阶组件的执行时机早于客户端水合完成。Gatsby 客户端水合完成前,组件的执行逻辑和浏览器端的上下文不匹配,
loginWithRedirect作为浏览器端 API 无法被高阶组件自动调用。
解决方案
- 方案1:把 Auth0Provider 的挂载逻辑放到 Gatsby 的
gatsby-browser.js和gatsby-ssr.js的wrapRootElement函数中,保证所有页面都能拿到初始化完成的 Auth0 实例,示例代码:
// gatsby-browser.js 和 gatsby-ssr.js 都需要添加这段代码 import React from "react" import { Auth0Provider } from "@auth0/auth0-react" export const wrapRootElement = ({ element }) => { return ( <Auth0Provider domain="你的Auth0域名" clientId="你的客户端ID" authorizationParams={{ redirect_uri: window.location.origin, }} > {element} </Auth0Provider> ) }
- 方案2:给受保护页面加 Auth0 加载状态判断,等初始化完成后再渲染高阶组件包裹的页面:
import * as React from 'react'; import { withAuthenticationRequired, useAuth0 } from '@auth0/auth0-react'; const UserIndexPage = () => { return ( <div> User index page </div> ); }; const ProtectedPage = withAuthenticationRequired(UserIndexPage, { onRedirecting: () => <div>Redirecting...</div> }); export default () => { const { isLoading } = useAuth0(); // 等Auth0初始化完成再渲染鉴权逻辑 if (isLoading) return <div>加载中...</div> return <ProtectedPage /> }
- 方案3:直接替换高阶组件为自定义的鉴权逻辑,和你现有手动调用
loginWithRedirect的逻辑兼容:
import * as React from 'react'; import { useAuth0 } from '@auth0/auth0-react'; import { useEffect } from 'react'; const UserIndexPage = () => { const { isAuthenticated, isLoading, loginWithRedirect } = useAuth0(); useEffect(() => { if (!isLoading && !isAuthenticated) { loginWithRedirect() } }, [isLoading, isAuthenticated, loginWithRedirect]) if (isLoading || !isAuthenticated) { return <div>Redirecting...</div> } return ( <div> User index page </div> ); }; export default UserIndexPage;
内容的提问来源于stack exchange,提问作者Joseph K.
相关产品推荐
相关产品推荐

