我遇到一种情况,我需要在页面呈现到服务器端并使用Next.js发送回给我之前,知道用户是否已登录,以避免UI发生闪烁变化。
我能够弄清楚如果用户已经使用此HOC组件登录,如何防止用户访问某些页面...
export const noAuthenticatedAllowed = (WrappedComponent: NextPage) => {
const Wrapper = (props: any) => {
return <WrappedComponent {...props} />;
};
Wrapper.getInitialProps = async (ctx: NextPageContext) => {
let context = {};
const { AppToken } = nextCookie(ctx);
if (AppToken) {
const decodedToken: MetadataObj = jwt_decode(AppToken);
const isExpired = () => {
if (decodedToken.exp < Date.now() / 1000) {
return true;
} else {
return false;
}
};
if (ctx.req) {
if (!isExpired()) {
ctx.res && ctx.res.writeHead(302, { Location: "/" });
ctx.res && ctx.res.end();
}
}
if (!isExpired()) {
context = { ...ctx };
Router.push("/");
}
}
const componentProps =
WrappedComponent.getInitialProps &&
(await WrappedComponent.getInitialProps(ctx));
return { ...componentProps, context };
};
return Wrapper;
};
这很棒。
现在,我如何构建类似的HOC组件,将其包装起来,比如说“ _app.tsx”,这样我就可以通过获取令牌并确定令牌是否过期并基于它来将“ userAuthenticated”属性传递给每个页面该道具我可以向用户显示适当的UI,而不会产生烦人的闪烁效果?
I hope you can help me with that, I tried to do it the same way I built the above HOC, but I couldn't do it, especially that Typescript doesn't make this any easier with its weird errors :(
Edit ============================================
I was able to create such HOC component and pass down the pro userAuthenticated
to each page like this ...
export const isAuthenticated = (WrappedComponent: NextPage) => {
const Wrapper = (props: any) => {
return <WrappedComponent {...props} />;
};
Wrapper.getInitialProps = async (ctx: NextPageContext) => {
let userAuthenticated = false;
const { AppToken} = nextCookie(ctx);
if (AppToken) {
const decodedToken: MetadataObj = jwt_decode(AppToken);
const isExpired = () => {
if (decodedToken.exp < Date.now() / 1000) {
return true;
} else {
return false;
}
};
if (ctx.req) {
if (!isExpired()) {
// ctx.res && ctx.res.writeHead(302, { Location: "/" });
// ctx.res && ctx.res.end();
userAuthenticated = true;
}
}
if (!isExpired()) {
userAuthenticated = true;
}
}
const componentProps =
WrappedComponent.getInitialProps &&
(await WrappedComponent.getInitialProps(ctx));
return { ...componentProps, userAuthenticated };
};
return Wrapper;
};
However I had to wrap every single page with this HOC in order to pass down the prop userAuthenticated
to the global layout that I have, because I couldn't wrap the "_app.tsx" class component with it, it always gives me an Error ...
This works ...
export default isAuthenticated(Home);
export default isAuthenticated(about);
But this doesn't ...
export default withRedux(configureStore)(isAuthenticated(MyApp));
因此,必须对每个页面都执行此操作,然后将属性传递到每个页面的全局布局中,而不是只在“ _app.tsx”中执行一次,这有点烦人。
我猜原因可能是因为“ _app.tsx”是类组件而不是像其余页面一样的功能组件?我不知道,我只是在猜测。
有什么帮助吗?