[NextAuth 공식문서 정리] Introduction - Getting Started

혜혜·2023년 11월 2일
0

Next.js

목록 보기
3/4
post-thumbnail

이번 프로젝트 소셜 로그인에 NextAuth를 적용해 보려고 한다. 공식 문서로 기본 개념 익히고 코드 짜 보면 좋을 것 같아서 혼자 간단하게 번역해 보면서 정리~!

Introduction

Introduction | NextAuth.js

  • NextAuth.js는 Next.js 애플리케이션을 위한 완벽한 오픈소스 인증 솔루션
  • 처음부터 Next.js와 Serverless를 지원하기 위해 설계됨

유연하고 사용하기 쉬움

  • 모든 OAuth 서비스와 작동하도록 설계되었으며,
    OAuth 1.0, 1.0A, 2.0 및 OpenID Connect 지원
  • 많은 유명한 회원가입 서비스를 위해 내장된 지원
  • 이메일 / 비밀번호없는 인증 지원
  • 모든 백엔드(Active Directory, LDAP, etc...)에서의 무상태 인증 지원
    → 무상태 : 말 그대로 상태를 유지하지 않는 것. 이전에 요청한 정보에 대해 서버가 알 수 없음
  • JSON Web 토큰과 DB 세션 둘 다 지원
  • Serverless로 설계되긴 했지만 어디서든 사용 가능(AWS Lambda, Docker, Heroku, etc...)

나만의 데이터 소유

NextAuth.js는 DB 있이/없이 사용될 수 있다!

  • 데이터를 지속적으로 제어할 수 있는 오픈소스 솔루션
  • BYOD(Bring Your Own Database)를 지원하며, 모든 데이터베이스와 함께 사용 가능
    → BYOD : 본인의 디바이스를 통해 데이터에 접근할 수 있는 것을 의미함.
  • MySQL, Postgres, SQL Server, MongoDB, SQLite 를 위해 내장된 지원
  • 유명한 호스팅 제공자들로부터의 데이터베이스와 잘 동작
  • 데이터베이스 없이도 사용 가능 (e.g. OAuth + JWT)

+) 이메일 회원가입은 일회성 인증 토큰을 저장하도록 구성된 데이터베이스 필요함

기본적으로 보안됨

  • 비밀번호 없는 로그인 매커니즘의 사용 장려
  • 기본적으로 안전하고, 사용자 데이터 보호를 위한 모범 사례를 장려하도록 설계됨
  • POST 경로(로그인, 로그아웃)에서 사이트 간 요청 위조 토큰(Cross-Site Request Forgery Tokens) 사용
  • 기본 쿠키 정책은 각 쿠키에 적합한 가장 제한적인 정책을 목표로 함
  • JSON 웹 토큰이 활성화되면, 기본적으로 (JWE) A256GCM을 사용하여 암호화됨
    → A256GCM : 암호화 알고리즘의 일종인듯?
  • 개발자 편의를 위해 대칭 서명 및 암호화 키를 자동 생성
  • 단기 세션을 지원하는 tab/window 동기화 및 연결 유지 메시지 기능
  • 개방형 웹 애플리케이션 보안 프로젝트(Open Web Application Security Project)에서 발표한 최신 지침을 구현하려는 시도

고급 옵션을 사용하면 로그인이 허용되는 계정 제어, JSON 웹 토큰 인코딩 및 디코딩을 처리하는 고유한 루틴을 정의하고, 사용자 정의 쿠키 보안 정책 및 세션 속성을 설정할 수 있으므로, 로그인 할 수 있는 사람세션이 얼마나 자주 재검증 되어야 하는지를 제어할 수 있다!

Getting Started

우리 프로젝트는 이미 개발 초기 단계이기 때문에, 이미 존재하는 프로젝트의 경우에 어떻게 NextAuth.js를 적용하는지만 살펴보자.

NextAuth 설치

npm install next-auth

✔️ 만약 TypeScript를 사용하고 있다면, NextAuth.js의 패키지 내에 타입 정의가 함께 제공된다.

API route 추가

프로젝트에 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에는 NaverProviderKakaoProvider도 있다!

공유 세션 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 간에 동기화하는 작업을 담당한다.

Frontend - React Hook 추가

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 훅은 애플리케이션의 어디에서든 사용할 수 있다고 한다!

Backend - API Route

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)로 값을 전달하려고 할 때, 다음과 같이 sessionjwt의 조합을 사용할 수 있다!

// 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>
}

callback URL 설정 (OAuth Only)

NextAuth.js 내장 providers나 custom provider를 통해 OAuth provider를 사용하고 있다면, provider 세팅에 callback URL을 설정해줘야 한다. 각 provider는 "Configuration" 섹션을 가진다. 여기 참고

production에 배포

사이트를 배포할 때, NEXTAUTH_URL 환경 변수를 웹 사이트의 표준 URL로 설정하라!

NEXTAUTH_URL=https://example.com

✨ 음 뭔가 어떤 개념인지 대충~?은 알 것 같다. 우리 프로젝트에서는 카카오 소셜 로그인을 구현할 것 같은데 관련 링크도 찾아봐야겠다😌

profile
쉽게만살아가면재미없어빙고

0개의 댓글