이번 프로젝트 소셜 로그인에 NextAuth를 적용해 보려고 한다. 공식 문서로 기본 개념 익히고 코드 짜 보면 좋을 것 같아서 혼자 간단하게 번역해 보면서 정리~!
NextAuth.js
는 Next.js 애플리케이션을 위한 완벽한 오픈소스 인증 솔루션
NextAuth.js
는 DB 있이/없이 사용될 수 있다!
MySQL
, Postgres
, SQL Server
, MongoDB
, SQLite
를 위해 내장된 지원+) 이메일 회원가입은 일회성 인증 토큰을 저장하도록 구성된 데이터베이스 필요함
고급 옵션을 사용하면 로그인이 허용되는 계정 제어, JSON 웹 토큰 인코딩 및 디코딩을 처리하는 고유한 루틴을 정의하고, 사용자 정의 쿠키 보안 정책 및 세션 속성을 설정할 수 있으므로, 로그인 할 수 있는 사람과 세션이 얼마나 자주 재검증 되어야 하는지를 제어할 수 있다!
우리 프로젝트는 이미 개발 초기 단계이기 때문에, 이미 존재하는 프로젝트의 경우에 어떻게 NextAuth.js를 적용하는지만 살펴보자.
npm install next-auth
✔️ 만약 TypeScript
를 사용하고 있다면, NextAuth.js
의 패키지 내에 타입 정의가 함께 제공된다.
프로젝트에 NextAuth.js
를 추가하려면, pages/api/auth
에 [...nextauth].js
라는 파일을 생성해야 한다.(아마 공식 문서는 Page Router 기준인 것 같다.) 이것은 모든 전역 NextAuth.js
설정과, NextAuth.js
를 위한 dynamic route handler를 포함하고 있다.
만약 App Router가 사용되는 Nextjs 13.2
버전 이상을 사용하고 있다면, 우리 가이드를 참고해 새로운 Route Handlers를 사용하여 초기 설정을 한다.
// /app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth"
const handler = NextAuth({
...
})
export { handler as GET, handler as POST }
↑ App Router 가이드를 참고하면 이런 식이지만, 공식 문서 Getting Started는 일단 Page Router 기준으로 설명되어 있어서 앞으로의 코드는 Page Router 기준으로 작성해 보도록 하겠다.
// pages/api/auth/[...nextauth].js
import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"
export const authOptions = {
// Configure one or more authentication providers
providers: [
GithubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
// ...add more providers here
],
}
export default NextAuth(authOptions)
/api/auth/*
(signIn
, callback
, signOut
, etc)에 대한 모든 요청은 자동적으로 NextAuth.js
에 의해 처리된다. 참고로 Provider에는 NaverProvider
와 KakaoProvider
도 있다!
공유 세션 state 설정
useSession
을 먼저 사용하려면, 애플리케이션의 최상위 수준에서 세션 컨텍스트 <SessionProvider />
가 있어야 한다.
// pages/_app.jsx
import { SessionProvider } from "next-auth/react"
export default function App({
Component,
pageProps: { session, ...pageProps },
}) {
return (
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
)
}
App Router에서는 아마 layout.tsx
에 해당되지 않을까 싶다...(확실치않음)
useSession
의 인스턴스는 그 다음 세션 data와 status에 접근할 것이다. <SessionProvider />
또한 세션을 업데이트하고 브라우저 탭과 window 간에 동기화하는 작업을 담당한다.
NextAuth.js
client의 useSession()
React Hook은 누가 로그인 했는지 확인하기 위한 가장 쉬운 방법이다!
// components/login-btn.jsx
import { useSession, signIn, signOut } from "next-auth/react"
export default function Component() {
const { data: session } = useSession()
if (session) {
return (
<>
Signed in as {session.user.email} <br />
<button onClick={() => signOut()}>Sign out</button>
</>
)
}
return (
<>
Not signed in <br />
<button onClick={() => signIn()}>Sign in</button>
</>
)
}
useSession
훅을 통해 로그인 데이터에 접근할 수 있는 것 같다. 참고로 useSession
훅은 애플리케이션의 어디에서든 사용할 수 있다고 한다!
API Route를 보호하기 위해, getServerSession()
을 사용할 수 있다.
// pages/api/restricted.js
import { getServerSession } from "next-auth/next"
import { authOptions } from "./auth/[...nextauth]"
export default async (req, res) => {
const session = await getServerSession(req, res, authOptions)
if (session) {
res.send({
content:
"This is protected content. You can access this content because you are signed in.",
})
} else {
res.send({
error: "You must be signed in to view the protected content on this page.",
})
}
}
NextAuth.js
Callbakcs 사용
NextAuth.js
를 사용하면 내장 callbacks을 통해 인증 플로우의 다양한 부분에 연결할 수 있다.
예를 들어, 로그인에서 프론트엔드(client side)로 값을 전달하려고 할 때, 다음과 같이 session
과 jwt
의 조합을 사용할 수 있다!
// pages/api/auth/[...nextauth].js
...
callbacks: {
async jwt({ token, account }) {
// Persist the OAuth access_token to the token right after signin
if (account) {
token.accessToken = account.access_token
}
return token
},
async session({ session, token, user }) {
// Send properties to the client, like an access_token from a provider.
session.accessToken = token.accessToken
return session
}
}
...
이제 getSession
이나 useSession
을 호출할 때마다, 반환되는 객체는 accessToken
값을 포함한다.
// components/accessToken.jsx
import { useSession, signIn, signOut } from "next-auth/react"
export default function Component() {
const { data } = useSession()
const { accessToken } = data
return <div>Access Token: {accessToken}</div>
}
NextAuth.js
내장 providers나 custom provider를 통해 OAuth provider를 사용하고 있다면, provider 세팅에 callback URL을 설정해줘야 한다. 각 provider는 "Configuration" 섹션을 가진다. 여기 참고
사이트를 배포할 때, NEXTAUTH_URL
환경 변수를 웹 사이트의 표준 URL로 설정하라!
NEXTAUTH_URL=https://example.com
✨ 음 뭔가 어떤 개념인지 대충~?은 알 것 같다. 우리 프로젝트에서는 카카오 소셜 로그인을 구현할 것 같은데 관련 링크도 찾아봐야겠다😌