如何在 Next.js 中为 auth 创建 HOC?
How to create HOC for auth in Next.js?
我想创建基本的 Next.js HOC 用于身份验证。我搜了下没弄明白
我的 Next.js 应用程序中有一个管理页面。我想从 http://localhost:4000/user/me
获取 URL return 是我的用户。如果用户数据 returns,组件必须被渲染。如果数据没有 return,我想重定向到 /admin/login
页面。
我试过这段代码,但没有用。我该如何解决这个问题?我也可以使用 useSWR
而不是 fetch
吗?
const withAuth = (Component, { data }) => {
if (!data) {
return {
redirect: {
destination: "/admin/login",
},
};
}
return Component;
};
withAuth.getInitialProps = async () => {
const response = await fetch("http://localhost:4000/user/me");
const data = await response.json();
return { data };
};
export default withAuth;
const AdminHome = () => {
return ();
};
export default withAuth(AdminHome);
服务器端身份验证
根据的回答,您可以为身份验证逻辑创建一个可重用的高阶函数。
如果用户数据不存在,它将重定向到登录页面。否则,该函数将继续调用包装的 getServerSideProps
函数,并将 return 合并的用户数据与页面中生成的 props。
export function withAuth(gssp) {
return async (context) => {
const response = await fetch('http://localhost:4000/user/me');
const data = await response.json();
if (!data) {
return {
redirect: {
destination: '/admin/login'
}
};
}
const gsspData = await gssp(context); // Run `getServerSideProps` to get page-specific data
// Pass page-specific props along with user data from `withAuth` to component
return {
props: {
...gsspData.props,
data
}
};
}
}
然后您可以在 AdminHome
页面上使用它来包装 getServerSideProps
函数。
const AdminHome = ({ data }) => {
return ();
};
export const getServerSideProps = withAuth(context => {
// Your normal `getServerSideProps` code here
return { props: {} };
});
export default AdminHome;
客户端认证
如果您希望在客户端完成身份验证,您可以创建一个高阶组件来包装您要保护的组件。
const withAuth = (Component) => {
const AuthenticatedComponent = () => {
const router = useRouter();
const [data, setData] = useState()
useEffect(() => {
const getUser = async () => {
const response = await fetch('http://localhost:4000/user/me');
const userData = await response.json();
if (!userData) {
router.push('/admin/login');
} else {
setData(userData);
}
};
getUser();
}, []);
return !!data ? <Component data={data} /> : null; // Render whatever you want while the authentication occurs
};
return AuthenticatedComponent;
};
然后您可以使用它直接包装 AdminHome
组件。
const AdminHome = () => {
return ();
};
export default withAuth(AdminHome);
我想创建基本的 Next.js HOC 用于身份验证。我搜了下没弄明白
我的 Next.js 应用程序中有一个管理页面。我想从 http://localhost:4000/user/me
获取 URL return 是我的用户。如果用户数据 returns,组件必须被渲染。如果数据没有 return,我想重定向到 /admin/login
页面。
我试过这段代码,但没有用。我该如何解决这个问题?我也可以使用 useSWR
而不是 fetch
吗?
const withAuth = (Component, { data }) => {
if (!data) {
return {
redirect: {
destination: "/admin/login",
},
};
}
return Component;
};
withAuth.getInitialProps = async () => {
const response = await fetch("http://localhost:4000/user/me");
const data = await response.json();
return { data };
};
export default withAuth;
const AdminHome = () => {
return ();
};
export default withAuth(AdminHome);
服务器端身份验证
根据
如果用户数据不存在,它将重定向到登录页面。否则,该函数将继续调用包装的 getServerSideProps
函数,并将 return 合并的用户数据与页面中生成的 props。
export function withAuth(gssp) {
return async (context) => {
const response = await fetch('http://localhost:4000/user/me');
const data = await response.json();
if (!data) {
return {
redirect: {
destination: '/admin/login'
}
};
}
const gsspData = await gssp(context); // Run `getServerSideProps` to get page-specific data
// Pass page-specific props along with user data from `withAuth` to component
return {
props: {
...gsspData.props,
data
}
};
}
}
然后您可以在 AdminHome
页面上使用它来包装 getServerSideProps
函数。
const AdminHome = ({ data }) => {
return ();
};
export const getServerSideProps = withAuth(context => {
// Your normal `getServerSideProps` code here
return { props: {} };
});
export default AdminHome;
客户端认证
如果您希望在客户端完成身份验证,您可以创建一个高阶组件来包装您要保护的组件。
const withAuth = (Component) => {
const AuthenticatedComponent = () => {
const router = useRouter();
const [data, setData] = useState()
useEffect(() => {
const getUser = async () => {
const response = await fetch('http://localhost:4000/user/me');
const userData = await response.json();
if (!userData) {
router.push('/admin/login');
} else {
setData(userData);
}
};
getUser();
}, []);
return !!data ? <Component data={data} /> : null; // Render whatever you want while the authentication occurs
};
return AuthenticatedComponent;
};
然后您可以使用它直接包装 AdminHome
组件。
const AdminHome = () => {
return ();
};
export default withAuth(AdminHome);