我可以检查 Auth0 用户是否已经在我的自定义 NextJS _app.js 级别登录?
Can I check if a Auth0 user is logged in already at the level of my custom NextJS _app.js?
正在使用 nextjs-auth0(我是全新的)进行身份验证的 NextJS 应用程序。我按照文档的建议用 UserProvider 包装了我的 _app.js 并使用 getInitialProps 将全局 online/offline 状态设置为整个应用程序如此;
import App from "next/app";
import { UserProvider} from '@auth0/nextjs-auth0';
export default function MyApp({Component, pageProps, status}) {
return (
<UserProvider>
<Component {...pageProps} status={status}/>
</UserProvider>
);
};
MyApp.getInitialProps = async (appContext) => {
const appProps = await App.getInitialProps(appContext);
const status = await getSiteStatus();
return {appProps, status};
};
这很好用,我可以获取网站的状态,如果我愿意的话,甚至可以在这里制作一个全球离线登陆页面。我还可以使用 useUser 挂钩从任何其他页面获取 auth0 会话。
但这里有一个问题:我想在所有内容上方设置一个全局 div 条带,通知用户 he/she 已登录并且可以看到该网站虽然它处于离线状态。因此,从字面上看,每个访问者都会遇到一个“离线”页面,而登录的人仍然可以访问所有其他页面,并被告知他们正在查看离线站点。
对我来说,最简单的方法就是将其简单地烘焙到应用程序页面中,与此风格相得益彰;
export default function MyApp({Component, pageProps, status, user}) {
if(status) {
return (
<UserProvider>
<Component {...pageProps} status={status}/>
</UserProvider>
);
} else if (user && !status) {
return (
<UserProvider>
<div class="somestyle">You are logged in but the site is offline!</div>
<Component {...pageProps} status={status}/>
</UserProvider>
} else {
return (
<SiteOffline />
)
};
大问题:在这种情况下如何获取 Auth0 用户会话并将其作为 user 传递?我不能使用 useUser 挂钩,因为 _app.js 本身没有包含在 UserProvider 中,因此会抛出错误 我不能使用挂钩这里。
我猜最好是通过 getInitialProps 以某种方式获得身份验证会话,但是没有钩子怎么办?似乎在任何地方都找不到像这样提到的任何场景,并且使用位于此组件和任何其他组件之间的附加包装器组件似乎非常尴尬。有什么想法吗?
您可以将逻辑移动到一个单独的组件来包装您的页面 Component
。
// components/page-wrapper
import { useUser } from '@auth0/nextjs-auth0';
export default function PageWrapper({ children, status }) {
const { user } = useUser();
return status || user ? (
<>
{!status && <div class="somestyle">You are logged in but the site is offline!</div>}
{children}
</>
) : (
<SiteOffline />
);
};
然后您将在 _app
中将其用作 UserProvider
的子项,从而提供对 useUser
挂钩的访问。
// pages/_app
import { UserProvider} from '@auth0/nextjs-auth0';
import PageWrapper from '<path-to>/components/page-wrapper'
export default function MyApp({ Component, pageProps, status }) {
return (
<UserProvider>
<PageWrapper status={status}>
<Component {...pageProps} status={status}/>
</PageWrapper>
</UserProvider>
);
};
感谢@juliomalves 提供的优雅解决方案!同时,我在处理此问题时还做了一些观察;
a) 使用 getInitialProps 将放弃自动静态优化,但 Nextjs 文档似乎暗示如果在每个希望优化的页面中定义 getStaticProps,您仍然可以得到蛋糕。没有确认这一点,文档还建议根本不要使用 getInitialProps。不过不确定如何以任何其他方式解决我的问题。
b) 更大的问题是网站的某些部分始终在线,例如 admin/user/backend 登录页面。直接在 app.js 中使用逻辑似乎很麻烦。当路由是 login/admin 页面时,我会以某种方式需要覆盖 Nextjs 路由器以在它到达 _app.js 之前绕过“离线”页面逻辑。不好看
所以最后,对于这种特殊情况,最有效的解决方案似乎是使用答案中的包装器,将状态传递给子级,然后让每个页面组件决定如何处理信息 -重定向到离线或忽略。
正在使用 nextjs-auth0(我是全新的)进行身份验证的 NextJS 应用程序。我按照文档的建议用 UserProvider 包装了我的 _app.js 并使用 getInitialProps 将全局 online/offline 状态设置为整个应用程序如此;
import App from "next/app";
import { UserProvider} from '@auth0/nextjs-auth0';
export default function MyApp({Component, pageProps, status}) {
return (
<UserProvider>
<Component {...pageProps} status={status}/>
</UserProvider>
);
};
MyApp.getInitialProps = async (appContext) => {
const appProps = await App.getInitialProps(appContext);
const status = await getSiteStatus();
return {appProps, status};
};
这很好用,我可以获取网站的状态,如果我愿意的话,甚至可以在这里制作一个全球离线登陆页面。我还可以使用 useUser 挂钩从任何其他页面获取 auth0 会话。
但这里有一个问题:我想在所有内容上方设置一个全局 div 条带,通知用户 he/she 已登录并且可以看到该网站虽然它处于离线状态。因此,从字面上看,每个访问者都会遇到一个“离线”页面,而登录的人仍然可以访问所有其他页面,并被告知他们正在查看离线站点。
对我来说,最简单的方法就是将其简单地烘焙到应用程序页面中,与此风格相得益彰;
export default function MyApp({Component, pageProps, status, user}) {
if(status) {
return (
<UserProvider>
<Component {...pageProps} status={status}/>
</UserProvider>
);
} else if (user && !status) {
return (
<UserProvider>
<div class="somestyle">You are logged in but the site is offline!</div>
<Component {...pageProps} status={status}/>
</UserProvider>
} else {
return (
<SiteOffline />
)
};
大问题:在这种情况下如何获取 Auth0 用户会话并将其作为 user 传递?我不能使用 useUser 挂钩,因为 _app.js 本身没有包含在 UserProvider 中,因此会抛出错误 我不能使用挂钩这里。
我猜最好是通过 getInitialProps 以某种方式获得身份验证会话,但是没有钩子怎么办?似乎在任何地方都找不到像这样提到的任何场景,并且使用位于此组件和任何其他组件之间的附加包装器组件似乎非常尴尬。有什么想法吗?
您可以将逻辑移动到一个单独的组件来包装您的页面 Component
。
// components/page-wrapper
import { useUser } from '@auth0/nextjs-auth0';
export default function PageWrapper({ children, status }) {
const { user } = useUser();
return status || user ? (
<>
{!status && <div class="somestyle">You are logged in but the site is offline!</div>}
{children}
</>
) : (
<SiteOffline />
);
};
然后您将在 _app
中将其用作 UserProvider
的子项,从而提供对 useUser
挂钩的访问。
// pages/_app
import { UserProvider} from '@auth0/nextjs-auth0';
import PageWrapper from '<path-to>/components/page-wrapper'
export default function MyApp({ Component, pageProps, status }) {
return (
<UserProvider>
<PageWrapper status={status}>
<Component {...pageProps} status={status}/>
</PageWrapper>
</UserProvider>
);
};
感谢@juliomalves 提供的优雅解决方案!同时,我在处理此问题时还做了一些观察;
a) 使用 getInitialProps 将放弃自动静态优化,但 Nextjs 文档似乎暗示如果在每个希望优化的页面中定义 getStaticProps,您仍然可以得到蛋糕。没有确认这一点,文档还建议根本不要使用 getInitialProps。不过不确定如何以任何其他方式解决我的问题。
b) 更大的问题是网站的某些部分始终在线,例如 admin/user/backend 登录页面。直接在 app.js 中使用逻辑似乎很麻烦。当路由是 login/admin 页面时,我会以某种方式需要覆盖 Nextjs 路由器以在它到达 _app.js 之前绕过“离线”页面逻辑。不好看
所以最后,对于这种特殊情况,最有效的解决方案似乎是使用答案中的包装器,将状态传递给子级,然后让每个页面组件决定如何处理信息 -重定向到离线或忽略。