ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Auth.js (구 Next Auth)를 사용하여 Next.js 인증 구현하기
    Next.js 2024. 1. 28. 17:57

    1. Auth.js

     공식문서에서 Auth.js란 웹 어플리케이션에서 인증을 위한 완벽한 오픈 소스 인증 솔루션이라고 설명하고 있다. 사실 Next Auth라는 이름으로 더 익숙한 이 라이브러리는, 4버전까지는 Next.js를 위한 솔루션이었으나, 5버전 부터는 Svelte, Express 등 더 많은 프레임 워크를 지원하며 Auth.js라는 이름으로 변경하였다. 확장성을 고려하여 이름을 바꾼 것 같다. 또한, 현재는 사실 베타 버전 즉 실험적 단계에 불과하여 Next Auth 공식문서와 Auth.js dev 공식문서를 번갈아가면서 확인하며 작성했다. 

     Auth.js 사용의 장점은 다음과 같다.

    - OAuth Provider를 통하여 다양한 OAuth 기능을 쉽게 사용할 수 있다. 현재 79개 이상의 유명한 서비스(구글, 페이스북, 애플, 카카오톡, 네이버 등) 지원, 자체 DB에 직접 접근하여 사용할 수 있으며 23개 이상의 DB/ORMs(MySQL, Postgres, Prisma)등 지원한다.

    - Email Provider를 통하여 내장된 이메일 / 패스워드 / 매직 링크 인증을 지원한다.

    - Credentail Provider를 통하여 기존 백엔드와의 유연한 연동도 가능하다.

    - 기본 보안기능

    • Signed, prefixed, server-only cookies
    • 내장된 CSRF protection
    • 클라이언트 사이드 자바스크립트에 의존하지 않음
    • 암호화된 JWT Session 

    * [자세한 내용은 공식문서]

    https://authjs.dev/getting-started/introduction#secure-by-default

    2. Auth.js 사용 방법

    API 라우트 구성하기

     먼저 Next.js 13이상 앱 라우팅 방식에서 Auth.js를 도입하기 위해서는 /pages/api/auth/[...nextauth] JS/TS 파일을 만들어서 API 라우트를 구성해야 한다. Next.js에서 새로 도입된 라우트 핸들러는 app 디렉토리에서만 사용할 수 있으며, 이 구조 방식은 REST 방식 요청과 유사하기 때문에 이 경로로 요청하기 위해서는 반드시 구성해주어야 한다.

    * [자세한 설명은 공식문서 확인]

    https://nextjs.org/docs/app/building-your-application/routing/route-handlers

     

    Routing: Route Handlers | Next.js

    Create custom request handlers for a given route using the Web's Request and Response APIs.

    nextjs.org

     Auth.js는 라우트 핸들러가 초기화되는 것을 감지하고, Web 인스턴스 요청을 이해하고 응답 인스턴스를 반환하여, 이 반환된 값을 통하여 여러 요청을 처리하게 된다. 또한, Auth.js가 제대로 작동하려면 GET, POST 핸들러가 필요하다.

    * [자세한 설명은 공식문서 확인]

    https://next-auth.js.org/configuration/initialization#route-handlers-app

    // src/app/api/auth/[...nextauth]/route.ts
    
    export { GET, POST } from '@/auth';
    
    // src/auth.ts
    import NextAuth from "next-auth"
    
    export const { 
    	handlers : { GET, POST } 
    } = NextAuth({
    	...
    })

     

    useSession Hook 사용하기

    useSession 훅을 통하여 Auth.js를 통하여 반환된 데이터를 사용하고 싶다면 Session Provider를 넣어주자.

    * [자세한 설명은 공식문서 확인]

    https://next-auth.js.org/getting-started/client#sessionprovider

     

    Client API | NextAuth.js

    The NextAuth.js client library makes it easy to interact with sessions from React applications.

    next-auth.js.org

    // src/app/(beforeLogin)/layout.tsx
    import { Inter } from 'next/font/google';
    import { SessionProvider } from "next-auth/react";
    
    type Props = {
    	children: React.ReactNode
    }
    
    export default function RootLayout({
    	children,
    }: Props) {
    	return (
        	<html lang="en">
            	<body className={inter.className}>
                	<SessionProvider>
                    	{children}
                    </SessionProvider>
                </body>
            </html>
        )
    }

     

    Credential Provider 설정하기

     Auth.js에서 제공하는 provider에는 3가지의 종류가 있다.

    - OAuth: 카카오톡, 네이버, 깃헙, 구글 등 사용자가 즐겨 사용하는 기존 로그인으로 로그인 할 수 있는 방법

    - Email: 하나 이상의 OAuth 서비스 외에 이메일을 통한 로그인 지원을 추가하면 사용자가 OAuth 계정에 엑세스 할 수 없는 경우 로그인 할 수 있는 방법

    - Credential: 사용자가 유연하게 로그인에 필요한 정보들을 구현하고, 인증 백엔드와 유연하게 통합할 수 있는 방법

    오늘은 백엔드와 로그인 할 수 있는 방법 Credential Provider에 대해서 알아보도록 하자.

     

     Auth.js 5버전 부터, authorize method만 정의하면 된다. authorize 콜백은 credentials 값을 통해 해당 사용자가 로그인이 가능한지 여부를 판단하여 로그인을 제어 할 수 있는 함수이며, 로그인 여부를 판단하는 api 응답 값을 통하여 제어할 수 있다. 로그인이 유효한 경우(응답 성공) User 객체를 반환한다. (이때, 반환된 객체는 auth 객체로 사용할 수 있으며, 또한 Session Provider 내부에서 상속 받는 컴퍼넌트들은 useSession hook을 이용하여 유저 객체를 받을 수 있다.) 또한, 유효하지 않은 경우는 null을 반환하여 쉽게 에러 핸들링을 할 수 있다.

    * [자세한 내용은 공식문서 확인]

     

    // src/auth.ts
    
    import NextAuth from "next-auth"
    import { cookies } from 'next/headers'
    import CredentialsProvider from "next-auth/providers/credentials";
    import cookie from 'cookie';
    
    export const {
      handlers: { GET, POST },
      auth,
      signIn,
    } = NextAuth({
      pages: {
        signIn: '/i/flow/login',
        newUser: '/i/flow/signup',    
      },
      providers: [
        CredentialsProvider({
          async authorize(credentials) {
            const authResponse = await fetch(`${process.env.AUTH_URL}/api/login`, {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
              },
              body: JSON.stringify({
                id: credentials.username,
                password: credentials.password,
              }),
            })
    
            // 백엔드 쿠키를 브라우저에 심는 부분
            let setCookie = authResponse.headers.get('Set-Cookie');
            if (setCookie) {
              const parsed = cookie.parse(setCookie)
              cookies().set('connect.sid', parsed['connect.sid'], parsed)
            } 
    
            if (!authResponse.ok) {
              return null
            }
    
            const user = await authResponse.json()
    
            return {
              email: user.id,
              name: user.nickname,
              image: user.image,
              ...user,
            }
          },
        }),
      ]
    });

     

    Auth.js에 로그인 요청하기

    자, 이제 export 해놓은 SignIn 함수에 credentials 인자와 id, password, redirect 값을 객체로 요청해주면 Auth.js에서 로그인 기능을 처리하게 된다.

    const onSubmit: FormEventHandler<HTMLFormElement> = async (e) => {
        e.preventDefault();
        setMessage('');
        try {
          const response = await signIn("credentials", {
              username: id,
              password,
              redirect: false,
            })
          if (!response?.ok) {
            setMessage('아이디와 비밀번호가 일치하지 않습니다.');
          } else {
            router.replace('/home');
          }
        } catch (err) {
          console.error(err);
          setMessage('아이디와 비밀번호가 일치하지 않습니다.');
        }
      };

     

     

     

     

     

     

     

    [출처]

    https://velog.io/@dosomething/Next-auth-%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B5%AC%ED%98%84

     

    Next-auth 를 이용한 로그인 구현

    next-auth 라이브러리를 이용해 로그인을 구현한 내용에 대해 공유합니다.

    velog.io

    https://velog.io/@leehyewon0531/NextAuth-%EA%B3%B5%EC%8B%9D%EB%AC%B8%EC%84%9C-%EC%A0%95%EB%A6%AC-Introduction-Getting-Started

Designed by Tistory.