用户认证+动态路由问题(Auth0 & next.js App Router)

问题描述 投票:0回答:2

我使用 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}`
      }
    }
  }
});

并期望进行一些验证,检查用户是否登录并将其返回到用户页面或登录页面。

auth0 next.js14 nextjs-dynamic-routing
2个回答
0
投票

欢迎来到 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}`;
  }
});

0
投票

感谢您的帮助!在听取了您关于使用 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}/`;
  },
});

希望这对其他人有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.