inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

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

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

155

svx327

작성한 질문수 1

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 입니다.


 

오류 상세 설명

 

간단히 말해, 애플리케이션이 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를 안전하게 처리하는지 확인하는 것도 중요합니다.

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

aws docker next.js nestjs prisma

답변 3

1

CrowKing77077

고생하시는 분들 있는 것 같아서 공유드립니다!

 

문제원인

  • NextAuth v5에서 Edge Runtime을 사용할 때 jsonwebtoken 라이브러리의 Node.js crypto 모듈 사용으로 인한 호환성 문제

해결방법

  1. jsonwebtokenjose 라이브러리로 교체

  2. auth.ts 의 jwt 내용을 다음과 같이 수정

 

...
import { SignJWT, jwtVerify } from "jose";
import { JWT } from "next-auth/jwt";

...

jwt: {
    encode: async ({ secret, token }) => {
      const secretKey = Array.isArray(secret) ? secret[0] : secret;
      return await new SignJWT(token)
        .setProtectedHeader({ alg: "HS256" })
        .setExpirationTime("1h")
        .sign(new TextEncoder().encode(secretKey));
    },
    decode: async ({ secret, token }) => {
      const secretKey = Array.isArray(secret) ? secret[0] : secret;
      if (!token || !secretKey) {
        throw new Error("Token or secret is missing");
      }
      const { payload } = await jwtVerify(
        token,
        new TextEncoder().encode(secretKey)
      );
      return payload as JWT;
    },
  },

 

0

svx327

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

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

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

0

인프런 AI 인턴

안녕하세요, 인프런 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 환경 문제 해결을 위한 방법과 예제를 제공합니다. 이 정보를 참고하시면서 코드 수정을 진행하시면 도움이 될 것입니다.

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

Node 관련 질문입니다

0

9

2

강의 내용속 커서 버젼하고 현재 커서 버젼이 다른가요?

0

13

2

맥북으로 RDP 연결 질문

0

13

1

라우팅 테이블 설정 중 궁금한게 있습니다.

0

26

1

노션 링크

0

25

3

노션 권한요청하였습니다 언제쯤 볼수있나요

0

28

2

클릭할 때 화면 울렁거리는게 집중에 방해가 돼요

0

85

1

prisma

0

85

1

nestjs controller 구현 중 user 객체 에러

0

76

1

shadcnui 의 button 의 cursor pointer 효과를 주는 방법

0

116

1

prisma-class-generator 사용시 generator 옵션 누락 추가함

0

99

1

Prisma schema 에서 relationship 관한 질문 이있습니다

0

88

1

File Upload 테스트 중 에러 발생 및 디버깅 방법

0

75

1

CKE Editor 관련 버전 질문

0

87

2

이상한 자막이 계속 보입니다.

0

67

1

JWT 발급을 Front에서 하는게 맞는건가요??

0

179

3

jotai 이후로 강의가 안맞네요;

0

252

3

Test 질문입니다.

0

69

0

The edge runtime does not support Node.js 'crypto' module.

0

257

5

토큰 쿠기 유실 원인

0

121

2

노션 링크 어디서 찾을 수 있나요?

0

225

2

로펀의 인프런 상담소 슬랙 채널 주소

0

167

3

개발툴에대해서

0

130

1

3000포트 겹치네요

0

157

2