NextAuth.js v4에서 JWT 인증 구현 및 활용 가이드 | 세상의 모든 정보

NextAuth.js v4에서 JWT 인증 구현 및 활용 가이드

NextAuth.js v4에서 JWT 인증 구현 및 활용 가이드

NextAuth.js v4를 사용하여 JWT 인증을 구현하고 활용하는 다양한 방법을 살펴보겠습니다.

1. JWT 설정


    import NextAuth from 'next-auth';
    import CredentialsProvider from 'next-auth/providers/credentials';

    export default NextAuth({
      providers: [
        CredentialsProvider({
          // 자격 증명 제공자 설정
        })
      ],
      jwt: {
        secret: process.env.JWT_SECRET,
        encryption: false, // JWT 암호화 비활성화
        maxAge: 60 * 60 * 24 * 30, // 30일
      },
      // 기타 설정...
    });
    

2. 커스텀 JWT 토큰 생성


    callbacks: {
      async jwt({ token, user }) {
        if (user) {
          token.id = user.id;
          token.role = user.role;
          token.customField = 'custom value';
        }
        return token;
      },
      async session({ session, token }) {
        session.user.id = token.id;
        session.user.role = token.role;
        session.customField = token.customField;
        return session;
      },
    },
    

3. API 라우트에서 JWT 검증


    import { getToken } from 'next-auth/jwt';

    export default async function handler(req, res) {
      const token = await getToken({ req, secret: process.env.JWT_SECRET });
      if (token) {
        // 토큰이 유효한 경우
        res.json({ message: 'Authenticated', user: token });
      } else {
        res.status(401).json({ message: 'Unauthorized' });
      }
    }
    

4. 미들웨어에서 JWT 활용


    import { withAuth } from 'next-auth/middleware';
    import { NextResponse } from 'next/server';

    export default withAuth(
      function middleware(req) {
        if (req.nextauth.token.role !== 'admin') {
          return NextResponse.rewrite(new URL('/unauthorized', req.url));
        }
      },
      {
        callbacks: {
          authorized: ({ token }) => token?.role === 'admin',
        },
      }
    );

    export const config = { matcher: ['/admin/:path*'] };
    

5. 클라이언트에서 JWT 사용


    import { useSession } from 'next-auth/react';
    import { useState, useEffect } from 'react';

    function ProfilePage() {
      const { data: session } = useSession();
      const [userDetails, setUserDetails] = useState(null);

      useEffect(() => {
        if (session) {
          fetch('/api/user-details', {
            headers: {
              'Authorization': `Bearer ${session.customField}`,
            },
          })
            .then(res => res.json())
            .then(data => setUserDetails(data));
        }
      }, [session]);

      if (!session) return 

Access Denied

; return (

Welcome, {session.user.name}

{userDetails &&

User Role: {userDetails.role}

}
); }

6. JWT 갱신 구현


    callbacks: {
      async jwt({ token, user }) {
        if (user) {
          token.accessToken = user.accessToken;
          token.refreshToken = user.refreshToken;
          token.accessTokenExpires = Date.now() + 60 * 60 * 1000; // 1 hour
        }

        // 액세스 토큰이 만료되지 않았다면 그대로 반환
        if (Date.now() < token.accessTokenExpires) {
          return token;
        }

        // 액세스 토큰이 만료되었다면 갱신
        return refreshAccessToken(token);
      },
      async session({ session, token }) {
        session.accessToken = token.accessToken;
        return session;
      },
    },

    async function refreshAccessToken(token) {
      try {
        // 리프레시 토큰을 사용하여 새 액세스 토큰 요청
        const response = await fetch('https://your-auth-server.com/token', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          body: `grant_type=refresh_token&refresh_token=${token.refreshToken}`,
        });

        const refreshedTokens = await response.json();

        if (!response.ok) {
          throw refreshedTokens;
        }

        return {
          ...token,
          accessToken: refreshedTokens.access_token,
          accessTokenExpires: Date.now() + refreshedTokens.expires_in * 1000,
          refreshToken: refreshedTokens.refresh_token ?? token.refreshToken, // 새 리프레시 토큰이 발급되지 않았다면 기존 것을 사용
        };
      } catch (error) {
        console.error('RefreshAccessTokenError', error);
        return {
          ...token,
          error: 'RefreshAccessTokenError',
        };
      }
    }
    

결론

NextAuth.js v4를 사용하여 JWT 인증을 구현하고 활용하는 다양한 방법을 살펴보았습니다. JWT를 통해 안전하고 효율적인 인증 시스템을 구축할 수 있으며, 서버 사이드와 클라이언트 사이드 모두에서 유연하게 활용할 수 있습니다. 보안을 강화하기 위해 HTTPS 사용, 토큰 만료 시간 설정, 그리고 주기적인 토큰 갱신 등의 추가적인 보안 조치를 고려하는 것이 좋습니다.

다음 이전

POST ADS1

POST ADS 2