🐥

【NextJs14】NextJs14 と 便利なライブラリ【#5Clerk Auth Middleware】

2023/12/14に公開

【#5Clerk Auth Middleware】

YouTube: https://youtu.be/z4ErRYXF6S4

https://youtu.be/z4ErRYXF6S4

今回はミドルウェアを使用して、
ログイン時にはトップページを表示できないように設定を追加します。

まずはプロテクトページを追加します。

app/(main)/protected/pages.tsx
import { UserButton } from "@clerk/nextjs";

const ProtectedPage = () => {
  return (
    <div>
      Protected Page: <UserButton afterSignOutUrl="/" />
    </div>
  );
};

export default ProtectedPage;

次にトップページのリンクを上記ページに設定します。

app/(home)/page.tsx
import Link from "next/link";
import { Button } from "@/components/ui/button";

export default function Home() {
  return (
    <main className="w-full h-full flex flex-col items-center justify-center">
      <h1 className="text-center text-3xl font-bold mb-2">WelCome Home</h1>
      <div className="flex items-center justify-center gap-x-2 mb-2">
        <Link href="/sign-in">
          <Button variant="primary">Sign In</Button>
        </Link>
        <Link href="/sign-up">
          <Button variant="outline">Sign Up</Button>
        </Link>
      </div>
      <div className="flex items-center justify-center">
        <Link href="/protected">
          <Button variant="link">Protected Page</Button>
        </Link>
      </div>
    </main>
  );
}

ここまでできましたら、middleware.tsに「afterAuth」の関数を追記します。

https://clerk.com/docs/references/nextjs/auth-middleware

middleware.ts
import { authMiddleware, redirectToSignIn } from "@clerk/nextjs";
import { NextResponse } from "next/server";

// This example protects all routes including api/trpc routes
// Please edit this to allow other routes to be public as needed.
// See https://clerk.com/docs/references/nextjs/auth-middleware for more information about configuring your Middleware
export default authMiddleware({
  publicRoutes: ["/"],
  afterAuth(auth, req) {
    if (auth.userId && auth.isPublicRoute) {
      let afterAuthPath = "/protected";
      const redirectPath = new URL(afterAuthPath, req.url);
      return NextResponse.redirect(redirectPath);
    }

    if (!auth.userId && !auth.isPublicRoute) {
      return redirectToSignIn({ returnBackUrl: req.url });
    }
  },
});

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

Discussion