지난 끄적임에서 왜 이렇게 안되는지에 대해 적었는데
(물론 포스트맨에서 사용해서 그런 걸 수 있긴 하지만)
일단 얘기해보자면 코드 자체는 그렇게 크게 문제가 없었다.
다만 Gateway든 다른 서비스에서든 생성한 커스텀 헤더를 클라이언트쪽에서 확인할 수 없는 문제였다.
즉, 생성된 커스텀 헤더들은 서버에서만 통한다는 얘기....
여기서 내가 생각하고 구현한 구조와 흐름과
통상적인 웹 동작에서의 구조와 흐름에 대한 차이 대해 조금 정리해보고자 한다.
일단 내가 구현한 흐름 자체는 로그인 요청이 수행되면 서버에서는 JWT를 생성하여 쿠키나 헤더를 통해 Gateway로 전달이 된다.
Gateway로 넘어온다면 쿠키에서 JWT를 추출하고
추출한 JWT를 기반으로 커스텀 헤더를 생성하여 Down Stream을 진행한다.
일반적인 웹 시스템에서는 사용자가 로그인하면 서버는 JWT(또는 세션 ID)를 HttpOnly 쿠키 또는 LocalStorage에 저장하게 된다.
이후의 모든 요청에서는 클라이언트(브라우저 또는 앱) 가 이 토큰을 보관하고,
서버로의 요청 시마다 Authorization 헤더에 붙이거나, 자동으로 쿠키를 전송하게 된다.
Authorization: Bearer <JWT_TOKEN>
혹은
Cookie: accessToken=xxx;
이 구조에서 핵심은 "클라이언트가 토큰을 소유"하고 있다는 점이다.
그래서 사용자는 로그인 이후에도 새로고침이나 다른 페이지 이동 등에서도 인증 상태를 유지할 수 있게 된다.
서버에서는 요청을 받을 때마다 클라이언트가 보낸 JWT를 검증하여 인증 처리를 진행하고,
필요한 경우에는 내부적으로 사용자 정보를 조회하거나 권한 확인을 하게 된다.
이 과정에서 추가적인 커스텀 헤더를 붙이는 경우도 있지만, 그것은 클라이언트가 아닌 서버 간 통신에서만 주로 사용된다.
정리하면, 내가 구현한 구조에서는
"JWT → 커스텀 헤더로 변환 → 이후 요청은 커스텀 헤더 기반" 이라는 방식이고,
클라이언트는 이 커스텀 헤더들을 알 수 없고, 사용할 수 없는 구조이다.
즉, 클라이언트는 인증 정보를 소유하지 않기 때문에, 로그인 이후 인증 유지가 어려워지는 문제가 생긴다.
(한 번 로그인하면 커스텀 헤더가 서버 간 통신에만 사용되므로, 클라이언트가 직접 다음 요청을 보낼 수 없는 구조)
그래서 생긴 이슈:
AI님들과 얘기를 조금 해봤는데
여러가지 방안을 알려주었다.
| 방안 | 설명 |
|---|---|
| JWT를 HttpOnly 쿠키로 계속 유지 | 서버에서 매 요청마다 JWT를 검증. 일반적인 방식이며 보안 좋음 |
| JWT를 LocalStorage에 저장하고 Authorization 헤더에 직접 붙이기 | 클라이언트가 제어 가능. SPA나 모바일 앱에서 많이 사용 |
| 커스텀 헤더 기반 인증 유지 시 | 클라이언트에 해당 헤더 값을 전달하는 구조를 별도로 설계하거나, Gateway가 지속적으로 붙여주는 구조 유지 필요 |
그런데 일단 내가 생각한 방안은 커스텀 헤더 기반 인증이기 때문에 다음 포스팅 부터는
커스텀 헤더 기반 인증 유지 하는 방법으로 문제를 해결하겠다.