참고했던 next-auth 홈페이지
🏴 https://next-auth.js.org/getting-started/client#usesession
🏴 https://next-auth.js.org/getting-started/example#add-api-route
ex)
const session = await getServerSession(authOptions);
const user = session?.user;
ex)
const {data: session} = useSession();
const user = session?.user;
그럼 context를 사용해보자! Next.js에서도 Context를 지원하는데 다만, client component로 만들어야 한다. 서버 컴포넌트에서는 직접적으로 접근할 수가 없기 때문이다.
서버와 클라이언트 환경에서 어떻게 렌더링하는지!
🏴 https://nextjs.org/docs/app/building-your-application/rendering
- 클라이언트 컴포넌트가 되는 경우
'use client'를 선언한 컴포넌트의 자식 컴포넌트가 자동으로 클라이언트 컴포넌트가 되려면, 자식 컴포넌트를 직접 import한 경우만 해당된다.- Context 컴포넌트의 경우
childrenprop을 통해 자식을 전달받는 컴포넌트는 자식 컴포넌트가 원래 환경(서버 또는 클라이언트)에서 동작할 수 있다.- AuthContext 예시
AuthContext같은 컴포넌트는 자식 컴포넌트가 서버 컴포넌트인지 클라이언트 컴포넌트인지 알 수 없고, 그 역할을 결정하지도 않는다.
=> 요약하자면 자식 컴포넌트까지 클라이언트 컴포넌트가 될지 안될지의 여부는 단순히 DOM Tree 구조로 결정되는 것이 아니라 import 여부에 따라 달라진다. 또한 AuthContext는 import해오는 것이 아니라 children prop으로 전달받기 때문에 자식이 자동적으로 클라이언트 컴포넌트가 되지 않는다.
'use client'
import {SessionProvider} from 'next-auth/react'
type Props = {
children: React.ReactNode
}
export default function AuthContext({ children }: Props) {
return (
<SessionProvider>
{children}
</SessionProvider>
)
}
👆 'use client' 선언해서 클라이언트 컴포넌트임을 명시한 후에 AuthContext 컴포넌트를 정의했다. SessionProvider로 감싸서 하위 컴포넌트들이 인증 세션에 접근할 수 있도록 한다.
import AuthContext from '@/context/AuthContext'
import SWRConfigContext from '@/context/SWRConfigContext'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={openSans.className}>
<body className='w-full bg-neutral-50 overflow-auto'>
<AuthContext>
<header className='sticky top-0 bg-white z-10 border-b'>
<div className='max-w-screen-xl mx-auto'>
<Navbar />
</div>
</header>
<main className='w-full flex justify-center max-w-screen-xl mx-auto'>
<SWRConfigContext>
{children}
</SWRConfigContext>
</main>
</AuthContext>
<div id='portal' />
</body>
</html>
)
}
👆 인스타그램 프로젝트에서는 사용자 정보를 표시해야 하는 header부터 mainRkwl 모두 AuthContext로 감쌌다. 이렇게 하니까 header와 main에 포함된 모든 컴포넌트들이 인증 세션이 접근할 수 있었다.
🖐 강의를 듣고 알게 된 로그인하는 과정을 상세하게 설명해두었다. 만약 next-auth가 로그인을 어떻게 가능하게 해주는지 궁금하다면 한번 읽어보는 것을 추천한다!
NextAuth 인증 시스템 콜백(callbacks)
🏴 https://next-auth.js.org/configuration/callbacks
import { addUser } from '@/service/user';
import NextAuth, { NextAuthOptions } from "next-auth"
import GoogleProvider from "next-auth/providers/google"
export const authOptions: NextAuthOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_OAUTH_ID || '',
clientSecret: process.env.GOOGLE_OAUTH_SECRET || '',
}),
],
callbacks: {
async signIn({ user: { id, name, image, email } }) {
if (!email) {
return false;
}
addUser({
id,
name: name || '',
image,
email,
username: email.split('@')[0]
});
return true
},
async session({ session, token }) {
const user = session?.user;
if (user) {
session.user = {
...user,
username: user.email?.split('@')[0] || '',
id: token.id as string,
};
}
return session
},
async jwt({ token, user }) {
if (user) {
token.id = user.id;
}
return token;
}
},
pages: {
signIn: '/auth/signin',
}
}
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };