솔루션을 만들며 가장 큰 부분을 차지하는게 회원가입 일 때가 많다.
npm i next-auth
api/auth/[...nextauth]
디렉토리 안에route.ts
파일을 만든다./app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth"
const handler = NextAuth({
...
})
export { handler as GET, handler as POST }
import NextAuth from "next-auth";
import NaverProvider from "next-auth/providers/naver";
...
const handler = NextAuth({
providers: [
NaverProvider({
clientId: process.env.NAVER_CLIENT_ID,
clientSecret: process.env.NAVER_CLIENT_SECRET,
}),
...
],
});
export { handler as GET, handler as POST };
|| ""
를 뒤에 붙여서 null이면 빈 문자열을 주도록 처리하고,네이버 개발자 홈페이지로 가서 APP을 만든다. 정말 간단하기 때문에 후다닥 해보기 바란다.
네이버 애플리케이션 등록 (API 이용신청) 링크
네이버 로그인만 사용한다고 체크한 다음, 받고 싶은 정보를 체크해주면 된다.
완료하고 나면 콘솔에서 Client ID 와 Secret이 보인다.
.env
파일을 만들고 NAVER_CLIENT_ID
와 NAVER_CLIENT_SECRET
변수를 선언한 다음 저 두 키를 적어준다.useSession
이라는 리액트 훅을 통해 접근할 수 있으며,<SessionProvider />
로 감싸두어야 한다.<SessionProvider />
를 감쌌다면, 이제는 layout.tsx에서 감싸자. 하지만 layout.tsx는 메타 데이터를 가지는 등 SSR을 사용해야 하기 때문에 상태가 필요한 프로바이더와 자꾸 충돌한다. 편법으로 그 안에 한번 더 컴포넌트로 감싸주자.AuthSession.tsx
'use client';
import { SessionProvider } from "next-auth/react";
type Props = ({
children: React.ReactNode;
});
export default function AuthSession({ children }: Props) {
return <SessionProvider>{children}</SessionProvider>;
}
app/layout.tsx
import "./globals.css";
import { Nanum_Gothic } from "next/font/google";
import AuthSession from "@/AuthSession";
const nanum_gothic = Nanum_Gothic({
subsets: ["latin"],
weight: ["400", "700", "800"],
});
export const metadata = {
title: "naver social sign-in by next-auth",
description: "Generated by create next app",
};
type Props = {
children: React.ReactNode;
};
export default function RootLayout({ children }: Props) {
return (
<html lang="en" className={nanum_gothic.className}>
<body>
<AuthSession>
{children}
</AuthSession>
</body>
</html>
);
}
"use client"; // 필수!
import { signIn, signOut, useSession } from "next-auth/react";
...세션 상태 사용하기
const { data: session } = useSession();
...
...로그인 버튼
<button onClick={() => signIn()}>
Sign In
</button>
...
...로그아웃 버튼
<button onClick={() => signOut()}>
Sign Out
</button>
...
이제 Appbar를 구성해보자.
로그인 하면 로그인한 사용자의 이름 혹은 이메일이 표시되었으면 좋겠고,
예쁘게 프로필 사진도 같이 나오게 만들면 좋겠다.
그리고 로그인 상태인지 로그아웃 상태인지 자동으로 판단하게 하려면 session?.user
가 null인지 아닌지를 가지고 구성하면 된다.
나는 네이버 로그인 기능에 '이메일'과 '프로필 이미지'를 필수로 달라고 했기 때문에
로그인 하면 로그인 버튼 옆에 이메일과 프로필 이미지가 출력되도록 한다.
"use client";
import { signIn, signOut, useSession } from "next-auth/react";
import Link from "next/link";
import React from "react";
const AppBar = () => {
const { data: session } = useSession();
return (
<div className="flex gap-5 p-2 bg-slate-200 ">
<Link className="text-sky-600 hover:text-sky-700" href={"/"}>
Home
</Link>
<div className="flex gap-2 ml-auto">
{session?.user ? (
<>
<img
className="w-8 h-8 rounded-full"
src={session.user.image || ""}
/>
<p className="text-sky-600"> {session.user.email}</p>
<button className="text-red-500" onClick={() => signOut()}>
Sign Out
</button>
</>
) : (
<button className="text-green-600" onClick={() => signIn()}>
Sign In
</button>
)}
</div>
</div>
);
};
export default AppBar;
덤으로 app/page.tsx
에서 session의 정보도 문자열로 출력하게 해봤다.
로그인 하지 않은 상태
데이터는 null, 상태는 unauthenticated(미인증)이다.
로그인을 완료한 상태
조금 더 예쁘게 만들어야겠지만.. 우선 정보들이 아주 잘 들어왔다.
session에는 우리가 네이버 로그인에서 요청한 정보만 들어오고
다른건 하나도 오지 않았음을 알 수 있다.
상태가 authenticated(인증됨)으로 변경되었다.
안녕하세요 :) 위에 글 따라 하는데 저는 layout 파일에, SessionProvider 감싼 AuthSession ('use client') 따로 만들어서 chidren 감쌌는데 오류가 납니다.. (터미널 에러 : StaticGenBailoutError: Page with
dynamic = "error"
), 혹시 이런 에러는 보시지 않으셨나요 ..?