我使用 app/api/[auth0]/route.ts 进行了基本的 Auth0 设置,因此用户可以登录/退出,但没有验证来检查用户并将其重定向到起始页面(如果用户尚未登录)。
所以我一直在尝试在我的个人资料页面上集成某种用户身份验证。但是我的个人资料(app/user-dashboard/[user_id]/page.tsx)页面配置了动态路由,如下所示:
export async function generateMetadata({
params,
}: {
params: { user_id: string };
}) {
return {
title: 'User Dashboard',
description: `Dashboard for User: ${params.user_id}`,
};
}
const UserDashboard = ({ params }: { params: { user_id: string } }) => {
... rest of page
与 nextjs 文档中的解释非常相似nextjs.org。 我尝试在此页面上实现“withPageAuthRequired”:像这样:
... rest of user page above.
export default withPageAuthRequired(UserDashboard, {
returnTo: ({ params }: AppRouterPageRouteOpts) => {
if (params) {
const user_id = params['user_id'];
if (typeof user_id === 'string') {
return `${process.env.NEXT_PUBLIC_BASE_URL}/user-dashboard/${user_id}`
}
}
}
});
但是我在“UserDashboard”上遇到一些打字稿错误:
Argument of type '({ params }: { params: { user_id: string; };}) => React.JSX.Element' is not assignable to parameter of type 'AppRouterPageRoute'.
Types of parameters '__0' and 'obj' are incompatible.
Type 'AppRouterPageRouteOpts' is not assignable to type '{ params: { user_id: string; }; }'.
Types of property 'params' are incompatible.
Type 'Record<string, string | string[]> | undefined' is not assignable to type '{ user_id: string; }'.
Type 'undefined' is not assignable to type '{ user_id: string; }'.ts(2345)
const UserDashboard: ({ params }: {
params: {
user_id: string;
};
}) => React.JSX.Element
我对 Auth0 很陌生,所以我不确定是否应该尝试使用“withPageAuthRequired”来检查用户是否登录。我发现文档非常抽象。
有人遇到过这个问题并知道该怎么办吗?
总而言之,尝试了这个:
export default withPageAuthRequired(UserDashboard, {
returnTo: ({ params }: AppRouterPageRouteOpts) => {
if (params) {
const user_id = params['user_id'];
if (typeof user_id === 'string') {
return `${process.env.NEXT_PUBLIC_BASE_URL}/user-dashboard/${user_id}`
}
}
}
});
并期望进行一些验证,检查用户是否登录并将其返回到用户页面或登录页面。
欢迎来到 StackOverflow!
您看到的错误来自预期类型 (
Record<string, string | string[]> | undefined
) 与您指定的类型user_id: string
不匹配。我同意在这方面文档有点缺乏。
我的建议是不要在
Page.tsx
中输入参数
const UserDashboard = ({ params }) => {
// ...
}
然后在使用参数之前检查它们是否有效,可以手动或使用验证库(例如Zod)。可能看起来像这样:
const UserDashboard = ({ params: rawParams }) => {
const params = z
.object({
user_id: z.string()
})
.safeParse(rawParams);
if (!params.success) redirect('/');
// ...
}
export default withPageAuthRequired(UserDashboard, {
returnTo: ({ params: rawParams }) => {
const params = z
.object({
user_id: z.string()
})
.safeParse(rawParams);
if (params.success) return `${process.env.NEXT_PUBLIC_BASE_URL}/user-dashboard/${user_id}`;
}
});
感谢您的帮助!在听取了您关于使用 Zod 的建议并尝试了不同的事情后,我发现这个解决方案满足了我的需求:
const UserDashboardSchema = z.object({
user_id: z.string(),
});
type UserParams = z.infer<typeof UserDashboardSchema>;
const UserDashboard: (
obj: AppRouterPageRouteOpts,
) => Promise<React.ReactElement> = async ({ params }) => {
if (!params || !('user_id' in params)) {
redirect(`${process.env.NEXT_PUBLIC_BASE_URL}/`);
}
... rest of page component.
在导出页面之前,我必须确保它(并且具有正确的道具)与
AppRouterPageRouteOpts
所需的类型相同:
export default withPageAuthRequired(UserDashboard, {
returnTo: (obj: AppRouterPageRouteOpts) => {
if (obj && obj.params && 'user_id' in obj.params) {
const { user_id } = obj.params;
return `${process.env.NEXT_PUBLIC_BASE_URL}/user-dashboard/${user_id}`;
}
return `${process.env.NEXT_PUBLIC_BASE_URL}/`;
},
});
希望这对其他人有帮助!