react

Next.js와 Hono 통합 환경에서 Authorization 헤더가 사라지는 이슈 해결기

jrpark91 2025. 6. 25. 19:44

Next.js app routerlayout.tsx(서버 컴포넌트)에서 데이터를 fetch를 해야 할 일이 생겼습니다.
서버는 Hono API 로 구성되어 있었는데 이 과정에서 Authorization 헤더가 사라지는 현상을 겪었습니다. 해당 문제를 분석하고 해결한 과정을 정리합니다.


문제 상황

프론트엔드: Next.js (App Router 기반)
백엔드: Hono (TypeScript 기반 API 서버)

인증은 accessToken을 쿠키에서 읽어서 Authorization 헤더로 전달하는 방식입니다.
API 호출은 hono/client의 hc()로 만든 clientApi를 통해 이루어졌습니다.

// clientApi 정의
export const clientApi = hc<AppType>(env.NEXT_PUBLIC_BASE_URL, {
  headers: () => {    
    return getHeaders().headers   
  },
})

서버 컴포넌트는 user-agent가 무조건 node여서 서버 액션(Server Actions)을 활용하여 이 API를 호출했더니 다음과 같은 문제가 발생했습니다:

  • Authorization 헤더가 분명히 들어간 것처럼 보임
  • Hono 서버에서는 ctx.req.header('Authorization') 값이 undefined
  • 결국 인증 실패 (401)

그런데 config.headers로 넘겼는데 왜 안 됐을까?

분명히 다음과 같이 Authorization 헤더를 직접 명시했습니다.

const response = await clientApi.api.v2.bundles['with-courses'].$get({ 
	config: { 
    	headers: {
        	Authorization: `Bearer ${accessToken}`
            } 
  	}
})
 

Hono 서버(정확히는 미들웨어)에서는 여전히 ctx.req.header('Authorization') 값이 undefined였습니다.


원인은 hc()의 fetch 내부 동작으로 추측됩니다.

hc()는 내부적으로 fetch()를 감싸서 사용하지만,
Next.js의 서버 액션이나 SSR 컨텍스트에서는 그 내부 fetch가 완전한 context를 공유하지 않는 것으로 보입니다.

즉, config.headers를 넣더라도

  • hc()의 내부 구현이 이 값을 정확히 fetch의 headers에 반영하지 않거나, Next.js 서버 실행 컨텍스트에서 예상대로 전달되지 않을 수 있는듯 합니다.
  • hc()는 내부적으로 fetch()를 wrapping하지만, Next.js의 Server Actions 컨텍스트에서는 config.headers가 무시되거나 적용되지 않아보입니다.
  • 즉, 헤더를 잘 넣었어도 실제 요청에는 포함되지 않고 있습니다.
  • 반면 fetch()는 그대로 동작하기 때문에 문제가 없습니다.

해결 방법

방법 1. 서버 액션에서는 fetch() 직접 사용

'use server' 

import { cookies } from 'next/headers'
export async function fetchBundleWithCoursesAction() { 
  const token = cookies().get('accessToken')?.value    
  const response = await fetch(`${process.env.API_SERVER_URL}/api/v2/bundles/with-courses`, { 
    headers: {    
      Authorization: `Bearer ${token}`,    
    },  
  })   
  if (!response.ok) throw new Error('API Error') 
  return await response.json()
 
  • 주의
    • process.env.API_SERVER_URL은 실제 Hono 서버 주소를 가리켜야 합니다.
    • rewrite 경로 (/.api/...)는 사용하지 않습니다.

정리

  • hono/client의 hc()는 클라이언트 호출용으로는 좋지만, 서버에서의 활용은 신중해야 합니다.
  • 서버에서 API 서버로 요청할 때는 rewrite 경로를 쓰지 말고, 실제 API 주소로 직접 fetch하는 게 가장 안전합니다.
  • 서버 액션과 같은 Next.js 서버 사이드 환경은 fetch와 headers 관리가 정밀하게 필요합니다.