我正在尝试自学 next.js,但我遇到了一些身份验证逻辑问题。
我有一个页面 protected/profile
,如果用户没有登录,我想阻止他们访问。为了检查这一点,我正在通过 getServerSideProps 检索一些用户数据,然后我试图将返回的用户数据传递给组件,然后组件将其传递给名为 Protected
的子元素。 Protected 是执行逻辑来检查用户是否登录,如果用户登录,则应通过返回 props.children 来显示个人资料页面。
如果用户没有登录,他们应该被重定向到 /
然而,看起来配置文件组件只是渲染配置文件页面,而不是等待受保护的逻辑完成。如果我在注销时尝试访问个人资料页面,我会收到一条错误消息,提示找不到 user.user_metadata,而实际上我应该被重定向。
控制台日志最终是
Profile log
protected.tsx:7 Protected log
protected.tsx:17 Protected: Has user
const Profile = ({user} : {user: User}) => {
console.log("Profile log");
return (
<Protected user={user}>
<h1>This is Profile</h1>
<h1>Hello, {user.user_metadata.full_name}!</h1>
<p> Your email : {user.email}</p>
</Protected>
)
}
export const getServerSideProps: GetServerSideProps = async ({req}) => {
const {user} = await supabaseClient.auth.api.getUserByCookie(req);
return { props: {user: user}}
}
export default Profile;
export default function Protected(props: {user: User, children}){
console.log("Protected log");
if(!props.user){
console.log("Protected: Null user");
return {
redirect: {
destination: "/",
permanent: false
}
}
}
console.log("Protected: Has user");
return props.children;
}
答案 0 :(得分:0)
所以,首先,正如我在评论中所说,你不能从 React 组件返回 redirect
对象,这是行不通的。如果您想使用 redirect
对象,您需要从 getServerSideProps
返回它。或者使用 useRouter
或类似的东西制作一些自定义逻辑。
其次,您应该输入 user
作为可选,因为它可能不存在(根据您的代码):
const Profile = ({user} : {user?: User}) => {
console.log("Profile log");
return (
<Protected user={user}>
<h1>This is Profile</h1>
<h1>Hello, {user.user_metadata.full_name}!</h1>
<p> Your email : {user.email}</p>
</Protected>
)
}
现在您将看到 Typescript 错误,您正在尝试从可能未定义的对象访问属性。
您可以做的是使用用户逻辑制作单独的组件:
const Profile = ({user} : {user?: User}) => {
console.log("Profile log");
return (
<Protected user={user}>
<UserProfile user={user} />
</Protected>
)
}
或让Protected
接受children as a function:
const Profile = ({ user }: { user?: User }) => {
console.log('Profile log');
return (
<Protected user={user}>
{() => (
<>
<h1>This is Profile</h1>
<h1>Hello, {user.user_metadata.full_name}!</h1>
<p> Your email : {user.email}</p>
</>
)}
</Protected>
);
};
Protected
大致如下所示:
export function Protected(props) {
if(!props.user){
// Make some other redirect logic, you current implementation with object won't work
}
// Notice here we calling the children
return props.children();
}