NextAuth.js

otto_dev·2022년 8월 18일
0

목록 보기
8/8
post-thumbnail

NextAuth.js 소개

NextAuth.js는 Next.js 애플리케이션을 위한 완전한 오픈 소스 인증 솔루션이다. Next.js와 Serverless를 지원하도록 설계되었다.

사용하기 쉽고 유연하다

  • 모든 OAuth 서비스가 작동되도록 설계
  • 많은 유명한 로그인 서비스 내장 지원
  • email과 password가 필요없는 인증
  • 모든 백엔드에서 stateless 인증 지원
  • JSON Web Token(JWT)과 DB 세션 모두 지원
  • Serverless를 위해 설계, AWS Lambda, Docker, Heroku 등에서 실행 가능.

개인 data

NextAuth.js는 DB 유무와 상관없이 사용 가능

  • 데이터를 계속 제어할 수 있는 오픈 소스 솔루션
  • 모든 데이터베이스와 함께 사용 가능
  • MySQL, MariaDB, Postgres, SQL Server, MongoDB, SQLite 내장 지원
  • OAuth+JWT처럼 DB 없이도 사용 가능
    Note: email 로그인을 할 경우 일회용 인증 토큰을 저장할 DB를 구성해야 함.

기본적인 보안

  • password없는 로그인 메커니즘 사용을 촉진
  • 유저 데이터 보호할 수 있도록 설계
  • POST 경로에서 사이트 간 요청 위조 토큰 사용
  • 기본 쿠키 정책은 각 쿠키에 적합한 가장 제한된 정책이 기본
  • JSON Web Token이 활성화 되면, 기본적으로 A256GCM를 통해 암호화된다.
  • 개발자의 편의를 위해 대칭 서명 및 암호화 키를 자동 생성
  • 단기 세션을 지원하는 탭/창 동기화 및 연결 유지 메시지 기능
  • Open Web Application Security Project의 최신 가이드 라인 구현 시도

시작하기

자세한 내용은 공식 홈페이지 문서에서 확인할 수 있다.
공식페이지에 따르면 몇 분 안에 인증 기능을 추가할 수 있다고 적혀있다.

NextAuth 설치

npm install next-auth
# or
yarn add next-auth
# or
pnpm add next-auth

API route 추가

pages/api/auth/[...nextauth].js

import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"
export default NextAuth({
  // Configure one or more authentication providers
  providers: [
    GithubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
    // ...add more providers here
  ],
})

NextAuth.js에 대한 동적 경로 처리가 포함되며, authentication provider 정보를 추가할 수 있다. github, google, facebook, twitter를 비롯해 kakao와 line도 설정 가능하다. 자세한 providers 정보

세션 상태 공유하기

pages/_app.jsx

import { SessionProvider } from "next-auth/react"
export default function App({
  Component,
  pageProps: { session, ...pageProps },
}) {
  return (
    <SessionProvider session={session}>
      <Component {...pageProps} />
    </SessionProvider>
  )
}

application의 최상위 레벨에서 <SessionProvider />로 감싸줘야 useSession을 사용할 수 있다. useSession의 인스턴스는 세션 데이터 및 상태에 액세스할 수 있다. <SessionProvider />는 브라우저 탭과 창 간에 세션을 업데이트하고 동기화하도록 관리한다.

하나에 탭에서 로그인 하면 열려 있는 모든 탭과 윈도우에서 세션을 공유한다. 로그아웃도 마찬가지.

Frontend - Add 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>
    </>
  )
}

NextAuth.js client에서 useSession() react hook은 누군가 로그인 했는지를 확인하는 가장 쉬운 방법이다. session값이 true이면 로그인 상태이고, false이면 로그인 상태가 아니다.

이 방법은 쉽고 빠르지만 로그인 상태가 아니더라도 페이지 정보가 노출된다.

Backend - API Route

pages/api/restricted.js

import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "./auth/[...nextauth]"
export default async (req, res) => {
  const session = await unstable_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 sign in to view the protected content on this page.",
    })
  }
}

unstable_getServerSession() method를 사용해 API 경로를 보호할 수 있다.

인증되지 않은 사용자에게는 page 정보 자체를 주지 않기 때문에 보안이 좋다. 그러나 서버에 부담이 커짐.

Extensibility

NextAuth.js Callback 함수

NextAuth.js는 내장 콜백함수를 통해 인증 과정의 다양한 부분에 연결할 수 있다. 예를 들어, 로그인에서 frontend로 값을 넘길 때, 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의 return 값에 accessToken값이 포함된다.
componenets/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>
}

Deployment

사이트를 배포할 때 NEXAUTH_URL 환경 변수를 웹사이트 표준 URL로 설정한다.

NEXTAUTH_URL=https://example.com
profile
공부 및 아카이브용 계정

0개의 댓글