SDK
Next.js SDK
@authon/nextjs — 라우트 미들웨어, 서버 컴포넌트 헬퍼, 완전한 React SDK를 갖춘 풀스택 Next.js 통합.
npm: @authon/nextjsNext.js 14+App Router
설치
bash
npm install @authon/nextjs환경 변수
Authon API 키를 .env.local. 에 추가하세요. Publishable key는 브라우저에 노출해도 안전하지만, secret key는 서버 측에만 보관하세요.
.env.local
NEXT_PUBLIC_AUTHON_PUBLISHABLE_KEY=pk_live_your_publishable_key
AUTHON_SECRET_KEY=sk_live_your_secret_key레이아웃에 AuthonProvider 추가
AuthonProvider 를 루트 레이아웃에 추가하여 모든 Client Component에서 인증 컨텍스트에 접근할 수 있게 하세요.
app/layout.tsx
import type { Metadata } from "next";
import { AuthonProvider } from "@authon/nextjs";
export const metadata: Metadata = {
title: "My App",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<AuthonProvider
publishableKey={process.env.NEXT_PUBLIC_AUTHON_PUBLISHABLE_KEY!}
>
{children}
</AuthonProvider>
</body>
</html>
);
}미들웨어
authonMiddleware 로 엣지에서 라우트를 보호하세요. 비공개 라우트에 대한 미인증 요청은 자동으로 로그인 페이지로 리디렉션됩니다.
middleware.ts
import { authonMiddleware } from "@authon/nextjs";
export default authonMiddleware({
// Routes that do NOT require authentication
publicRoutes: ["/", "/about", "/pricing", "/sign-in", "/sign-up"],
// Where to redirect unauthenticated users (default: /sign-in)
signInUrl: "/sign-in",
});
export const config = {
// Apply middleware to all routes except Next.js internals and static files
matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\.png$).*)"],
};서버 컴포넌트
서버 컴포넌트와 서버 액션에서 @authon/nextjs/server.
auth()
사용자 ID와 토큰 게터를 포함한 세션 메타데이터를 반환합니다. 경량 — 전체 사용자 객체를 가져오지 않습니다.
app/api/orders/route.ts
import { auth } from "@authon/nextjs/server";
import { NextResponse } from "next/server";
export async function GET() {
const { userId, getToken } = await auth();
if (!userId) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const token = getToken();
// Use token to call external APIs on behalf of the user
const orders = await fetchOrders(userId, token);
return NextResponse.json({ orders });
}currentUser()
전체 AuthonUser 객체를 가져와 반환합니다. 서버 컴포넌트에서 사용자 프로필 데이터가 필요할 때 사용하세요.
app/dashboard/page.tsx
import { currentUser } from "@authon/nextjs/server";
import { redirect } from "next/navigation";
export default async function DashboardPage() {
const user = await currentUser();
// Redirect if not signed in
if (!user) {
redirect("/sign-in");
}
return (
<main>
<h1>Welcome back, {user.displayName ?? user.email}!</h1>
<p>Account created: {new Date(user.createdAt).toLocaleDateString()}</p>
<p>Sign-in count: {user.signInCount}</p>
</main>
);
}클라이언트 훅 & 컴포넌트
모든 React SDK 훅과 컴포넌트는 Client Component에서 동작합니다. @authon/nextjs에서 임포트하세요 (@authon/react의 모든 것을 재내보냅니다).
components/Header.tsx
"use client";
import Link from "next/link";
import { SignedIn, SignedOut, UserButton, useAuthon } from "@authon/nextjs";
export function Header() {
const { openSignIn } = useAuthon();
return (
<header className="flex items-center justify-between p-4 border-b">
<Link href="/">My App</Link>
<div className="flex items-center gap-3">
<SignedIn>
<Link href="/dashboard">Dashboard</Link>
<UserButton />
</SignedIn>
<SignedOut>
<button onClick={() => openSignIn()} className="btn-primary">
Sign in
</button>
</SignedOut>
</div>
</header>
);
}API 라우트 보호
auth():
app/api/profile/route.ts
import { auth } from "@authon/nextjs/server";
import { currentUser } from "@authon/nextjs/server";
import { NextResponse } from "next/server";
export async function GET() {
const { userId } = await auth();
if (!userId) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const user = await currentUser();
return NextResponse.json({ user });
}
export async function PATCH(request: Request) {
const { userId } = await auth();
if (!userId) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const body = await request.json();
// Update user profile...
return NextResponse.json({ success: true });
}로그인 / 회원가입 페이지
임베드 모달 컴포넌트로 전용 로그인 및 회원가입 페이지를 만드세요:
app/sign-in/page.tsx
import { SignIn } from "@authon/nextjs";
export default function SignInPage() {
return (
<div className="flex min-h-screen items-center justify-center bg-slate-950">
<SignIn mode="embedded" />
</div>
);
}app/sign-up/page.tsx
import { SignUp } from "@authon/nextjs";
export default function SignUpPage() {
return (
<div className="flex min-h-screen items-center justify-center bg-slate-950">
<SignUp mode="embedded" />
</div>
);
}