Inflearn brand logo image

인프런 커뮤니티 질문&답변

svx327님의 프로필 이미지
svx327

작성한 질문수

인프런 클론코딩 Part 1: Next.js와 NestJS로 시작하는 실전 프로젝트

[BE] 백엔드 Auth Guard 구현 시작. Auth Guard로 유저 아이디 가져오는 부분 작업

[auth][error] JWTSessionError: Read more at...

해결된 질문

작성

·

59

0

강의

25. [BE] 백엔드 Auth Guard 구현 시작. Auth Guard로 유저 아이디 가져오는 부분 작업

타임라인 19:55

여기까지는 정상적으로 진행됩니다.

쿠키에서 "authjs.session-token" 확인이 가능합니다.

image.png

 

 


image.png

 

import NextAuth from "next-auth";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { prisma } from "@/prisma";
import CredentialsProvider from "next-auth/providers/credentials";
import { comparePassword } from "@/lib/password-utils";
import * as jwt from "jsonwebtoken";
import { JWT } from "next-auth/jwt";

export const { handlers, auth, signIn, signOut } = NextAuth({
  useSecureCookies: process.env.NODE_ENV === "production",
  trustHost: true,
  adapter: PrismaAdapter(prisma),
  secret: process.env.AUTH_SECRET,
  providers: [
    CredentialsProvider({
      name: "credentials",
      credentials: {
        email: {
          label: "이메일",
          type: "email",
          placeholder: "이메일 입력",
        },
        password: {
          label: "비밀번호",
          type: "password",
        },
      },
      async authorize(credentials) {
        // 1. 모든 값들이 정상적으로 들어왔는가?
        if (!credentials || !credentials.email || !credentials.password) {
          throw new Error("이메일과 비밀번호를 입력해주세요.");
        }

        // 2. DB에서 유저를 찾기
        const user = await prisma.user.findUnique({
          where: {
            email: credentials.email as string,
          },
        });

        if (!user) {
          throw new Error("존재하지 않는 이메일입니다.");
        }

        // 3. 비밀번호 일치 여부 확인
        const passwordMatch = comparePassword(
          credentials.password as string,
          user.hashedPassword as string
        );

        if (!passwordMatch) {
          throw new Error("비밀번호가 일치하지 않습니다.");
        }

        return user;
      },
    }),
  ],
  session: {
    strategy: "jwt",
  },
  jwt: {
    encode: async ({ token, secret }) => {
      return jwt.sign(token as jwt.JwtPayload, secret as string);
    },
    decode: async ({ token, secret }) => {
      return jwt.verify(token as string, secret as string) as JWT;
    },
  },
  pages: {},
  callbacks: {},
});

 

image.png

 

 

FE 추가분

/frontend/auth.ts

// ... 중략
import * as jwt from "jsonwebtoken";
import { JWT } from "next-auth/jwt";

export const { handlers, auth, signIn, signOut } = NextAuth({
	// ...중략
	jwt: {
		encode: async ({ token, secret }) => {
			return jwt.sign(token as jwt.JwtPayload, secret as string);
		},
		decode: async ({ token, secret }) => {
			return jwt.verify(token as string, secret as string) as 
			JWT;
		},
	},
	// ... 중략
}) 
pnpm add jsonwebtoken
pnpm add -D @types/jsonwebtoken

 

GET /api/auth/csrf 200 in 47ms

POST /api/auth/callback/credentials? 200 in 114ms

[auth][error] JWTSessionError: Read more at https://errors.authjs.dev#jwtsessionerror

[auth][cause]: Error: The edge runtime does not support Node.js 'crypto' module.

Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime

at Object.get (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\_6e5868ec._.js:62:41)

at C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\node_modules__pnpm_d2b00409._.js:8647:62

at getSecret (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\node_modules__pnpm_d2b00409._.js:8630:20)

at push.[project]/node_modules/.pnpm/jsonwebtoken@9.0.2/node_modules/jsonwebtoken/verify.js [middleware-edge] (ecmascript).module.exports (C:\Users\svx32\OneDrive\바 탕 화면\v5\frontend\.next\server\edge\chunks\node_modules__pnpm_d2b00409._.js:8633:12)

at Object.decode (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\[root-of-the-server]__273b5c62._.js:137:233)

at session (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\fdcd2_@auth_core_ec592ae5._.js:4516:39)

at AuthInternal (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\fdcd2_@auth_core_ec592ae5._.js:5123:269)

at async Auth (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\fdcd2_@auth_core_ec592ae5._.js:5379:34)

at async handleAuth (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\node_modules__pnpm_d2b00409._.js:3913:29)

at async C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\_6e5868ec._.js:12505:20

[auth][details]: {}

GET / 200 in 62ms

---

 

이 오류 메시지는 애플리케이션이 Edge Runtime 환경에서 Node.js의 crypto 모듈을 사용하려고 시도할 때 발생하는 JWTSessionError 입니다.


 

오류 상세 설명

 

  • JWTSessionError: 이는 JWT(JSON Web Token) 세션 관리 중에 문제가 발생했음을 나타냅니다. JWT는 웹 애플리케이션에서 사용자 세션을 처리하는 일반적인 방법입니다.

  • The edge runtime does not support Node.js 'crypto' module.: 이 부분이 핵심 문제입니다. Edge Runtime (예: Next.js Edge Functions 또는 Middleware)은 빠르고 가볍게 설계된 환경입니다. 따라서 모든 Node.js API를 지원하지 않으며, 특히 암호화, 해싱, 디지털 서명 등에 사용되는 crypto 모듈을 포함하지 않습니다. JWT 작업은 이 crypto 모듈에 크게 의존합니다.

  • 스택 트레이스 분석: 오류 스택 트레이스를 보면 jsonwebtoken 패키지(특히 verify 작업 중)에서 crypto 모듈에 접근하려고 시도하며, 이 과정이 @auth/core(일반적으로 Auth.js 라이브러리)에서 호출됩니다. 이는 JWT 유효성 검사 프로세스가 crypto 모듈의 부재로 인해 실패하고 있음을 명확히 보여줍니다.

간단히 말해, 애플리케이션이 Edge Runtime이라는 제한된 서버리스 환경에서 JWT 유효성 검사(보안 관련 작업)를 수행하려고 하지만, 이 환경에는 해당 작업을 위한 필수 도구(crypto 모듈)가 없기 때문에 오류가 발생하는 것입니다.


 

해결 방법 (일반적인 접근)

 

이 문제를 해결하기 위해서는 주로 다음 방법들을 고려할 수 있습니다:

  1. JWT 관련 작업을 Edge Runtime 외부로 이동: JWT 유효성 검사와 같이 crypto 모듈이 필요한 작업은 Edge Runtime이 아닌 일반적인 Node.js 서버 환경(예: Next.js의 표준 API 라우트)에서 수행하도록 변경해야 합니다.

  2. 인증 라이브러리 설정 변경: 사용하고 있는 인증 라이브러리(Auth.js)의 세션 전략을 변경하여 Edge Runtime 컨텍스트에서 crypto 모듈에 의존하지 않도록 구성해야 합니다. 예를 들어, JWT 기반 세션 대신 데이터베이스 세션과 같은 다른 세션 관리 방식을 고려할 수 있습니다.

  3. AUTH_SECRET 확인: 직접적인 원인은 아니지만, AUTH_SECRET 환경 변수가 올바르게 설정되어 있고, 사용 중인 환경에 맞게 JWT를 안전하게 처리하는지 확인하는 것도 중요합니다.

어떻게 해결해야하나요??

답변 2

0

svx327님의 프로필 이미지
svx327
질문자

middleware.ts 파일위치를 바꾸는 것으로 해결됨

강의 23번 타임라인 1:13 지점에서
middleware.ts 파일 위치를 변경합니다.

middleware.ts
기존 파일 위치 : frontend
변경 파일 위치 : frontend/app

0

안녕하세요, 인프런 AI 인턴입니다. svx327님.

Next.js의 Edge Runtime 환경에서 발생하고 있는 JWTSessionError에 대해 설명드리겠습니다. 이 오류는 주로 Edge 환경에서 Node.js의 특정 모듈이 지원되지 않기 때문에 발생합니다. 특히 crypto 모듈의 부재가 JWT 관련 작업에 영향을 미치고 있습니다.

문제 요약

  • Edge 컴퓨팅 환경은 빠르고 가벼운 서비스를 위해 설계되었기 때문에 모든 Node.js 모듈을 지원하지 않습니다. 이로 인해 crypto 모듈에 의존하는 JWT 작업이 실패하고 있습니다.

해결 방법

  1. Node.js 환경으로 전환하기:

    • crypto 모듈을 사용하는 JWT 작업을 일반 Node.js 서버 환경에서 수행하시기 바랍니다. 이는 JWT 유효성 검사 등의 작업을 Next.js의 API Routes를 통해 처리하는 것을 의미합니다.
  2. 대체 라이브러리 사용하기:

    • Edge 환경에서도 사용할 수 있는 WebCrypto API나 다른 대체 암호화 라이브러리를 활용하여 JWT 처리를 구현할 수 있습니다.
  3. 환경 설정 및 구성 확인하기:

    • AUTH_SECRET이나 기타 환경 변수 설정이 올바르게 되어 있는지 확인해 주세요. 이는 JWT의 인코딩 및 디코딩 과정에서 보안성을 보장합니다.

추가 자료

자세한 설명과 예제는 아래 게시물에서도 확인하실 수 있습니다:
- Edge 환경에서 JWT 사용 문제 해결하기

위 링크에서는 Edge 환경 문제 해결을 위한 방법과 예제를 제공합니다. 이 정보를 참고하시면서 코드 수정을 진행하시면 도움이 될 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

svx327님의 프로필 이미지
svx327

작성한 질문수

질문하기