Next-Intl 与 Clerk 集成

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

我已经看过 Next.js Clerk 与 NextIntl 的对比。中间件冲突

我已经测试了 next-intl 和 clerk v5 之间的集成,并且 /api 文件夹的使用被阻止,因为它引发了 404。看起来在启用 /api 路径并保护它时存在冲突。

这是我在中间件中的配置:

import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
import createMiddleware from "next-intl/middleware";
import { NextResponse } from "next/server";
import { defaultLocale, locales } from "./messages/config";

const intlMiddleware = createMiddleware({
  locales: locales,
  defaultLocale: defaultLocale,
  alternateLinks: false,
  localePrefix: "as-needed",
});

const isProtectedRoute = createRouteMatcher(["/:locale/(.*)", "/", "/api/:path*"]);

export default clerkMiddleware((auth, req) => {
  const { pathname } = req.nextUrl;

  if (pathname.includes("/:locale/")) {
    const locale = pathname.split("/")[1];
    const replacedPathname = pathname.replace("/:locale/", "");
    return NextResponse.redirect(
      new URL(`/${(locales.includes(locale) ?? locale) || defaultLocale}/${replacedPathname}`, req.url),
    );
  }

  if (isProtectedRoute(req)) {
    auth().protect();
  }

  return intlMiddleware(req);
});

export const config = {
  matcher: ["/((?!api/config/:path*).*)", "/((?!_next|_vercel|.*\\..*).*)"],
};

这是我的文件夹结构:

enter image description here

这是我的 .env.local 文件的(一部分):

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/:locale/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/:locale/sign-up

任何有关配置匹配器和保护部分或全部 /api 路由的帮助都会很棒。

我按照指南进行操作,并预计 /api 文件夹将受到保护,但引发了 404。

next.js next.js14 clerk next-intl
1个回答
0
投票

这就是我所做的。我希望 Clerk 保护某些本地化路由和某些 api 路由。我不希望 Next-Intl 本地化我的 api 路由。

我的文件结构与你的类似,只是我的注册路径是 \sign-up[[...sign-up]]\page.tsx

我使用默认环境配置,效果很好

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up

我通过在中间件中这样列出本地化路由来保护它们。

const isProtectedRoute = createRouteMatcher([
   "/:locale/dashboard(.*)",
   "/:locale/my-account(.*)",
]);

另外,在中间件中,我确保 Clerk 和 Next-Intl 都在除静态页面之外的任何地方运行。我的中间件匹配器如下所示:

export const config = {
    matcher: "/((?!static|.*\\..*|_next).*)",
};

在 ClerkMiddleware 内部,我检查 Next-Intl 是否在 api 路由上运行。这是我的代码:

export default clerkMiddleware((auth, req) => {
    // Restrict admin routes to users with specific permissions
    if (isProtectedRoute(req)) {
        auth().protect({});
    }

    // do not localize api routes
    const path = req.nextUrl.pathname;
    if (path.includes("/api")) {
        return;
    }

    return intlMiddleware(req);
});

最后在每个 api 路由中我添加了这样的 Clerk 身份验证。

import { auth } from "@clerk/nextjs/server";

export async function POST(request) {
    // check if admin
    const { has } = auth();
    if (!has({ role: "org:admin" })) {
        return new Response("You do not have rights", {
            status: 401,
        });
    }

    // Here is your route logic
}
© www.soinside.com 2019 - 2024. All rights reserved.