Skip to content

[Fix] 토큰 재발급 로직 변경 및 로그인 시 토큰 쿠키에 담는 것으로 변경#64

Merged
TwoMuchSilver merged 4 commits intodevfrom
fix/token-refresh
Mar 9, 2026
Merged

[Fix] 토큰 재발급 로직 변경 및 로그인 시 토큰 쿠키에 담는 것으로 변경#64
TwoMuchSilver merged 4 commits intodevfrom
fix/token-refresh

Conversation

@imeasy99
Copy link
Copy Markdown
Collaborator

@imeasy99 imeasy99 commented Mar 5, 2026

📝 작업 내용

정리

구분 Access Token (AT) Refresh Token (RT)
변경 전 Authorization 헤더 (Bearer ) HttpOnly 쿠키 refreshToken
변경 후 HttpOnly 쿠키 accessToken HttpOnly 쿠키 refreshToken

변경된 토큰 재발급 로직

  1. 🛡️ 토큰 정책 및 보안 강화
  • 쿠키 중심 인증: 기존 Authorization 헤더 반환 방식을 제거하고, accessToken과 refreshToken을 모두 HttpOnly 쿠키에 담아 반환하도록 통일했습니다. (XSS 공격 방지 및 FE 구현 단순화)
  • 토큰 추출 우선순위: API Gateway 필터(JwtAuthenticationFilter)에서 쿠키를 최우선으로 확인하며, 쿠키가 없을 때만 헤더(Authorization: Bearer)를 확인하는 폴백 로직을 적용했습니다.
  • 엄격한 검증: accessToken 쿠키가 존재하지만 값이 비어있는 경우, 유효하지 않은 세션으로 간주하여 즉시 401 Unauthorized를 반환하도록 개선했습니다.
  1. 🔄 사일런트 리프레시 (Silent Refresh) 구현
  • 자동 갱신: introspect API 호출 시 Access Token(AT)의 만료 시간이 5분(300초) 미만으로 남았거나 이미 만료된 경우, 유효한 리프레시 토큰이 있다면 자동으로 새 AT/RT를 발급합니다.
  • FE/사용자 무중단: 재발급된 토큰은 응답의 Set-Cookie 헤더를 통해 자동으로 브라우저에 저장되므로, 프론트엔드에서 별도의 리프레시 로직(인터셉터 등)을 짤 필요가 없습니다
  • 강제 로그아웃 로직: 리프레시 토큰이 만료되었거나 재발급에 실패할 경우, 기존에 남아있던 모든 쿠키를 즉시 만료(Max-Age=0)시켜 세션을 깔끔하게 정리하고 401을 반환합니다.
graph TD
    Start["인트로스펙트 호출 (/api/v1/auth/introspect)"] --> ExtractToken["토큰 추출 (JwtAuthenticationFilter.extractToken)"]
    
    subgraph Extraction["[1] 토큰 추출 우선순위"]
        ExtractToken --> CheckCookie{"accessToken 쿠키 존재?"}
        CheckCookie -- "예" --> UseCookie["쿠키 값 사용 (헤더 무시)"]
        CheckCookie -- "아니오" --> CheckHeader{"Authorization 헤더 존재?"}
        CheckHeader -- "예" --> UseHeader["헤더 값 사용"]
        CheckHeader -- "아니오" --> NoToken["토큰 없음 결정"]
    end

    UseCookie --> ValidateEmpty
    UseHeader --> ValidateEmpty
    NoToken --> Fail401["401 Unauthorized 반환"]

    subgraph Validation["[2] 검증 및 재발급 판단"]
        ValidateEmpty --> IsEmpty{"토큰 값이 비어있음?"}
        IsEmpty -- "예" --> Fail401
        IsEmpty -- "아니오" --> CheckTime{"만료됨 OR 남은 시간 < 5분?"}
        
        CheckTime -- "예 (갱신 필요)" --> CheckRT{"refreshToken 쿠키 존재?"}
        CheckRT -- "아니오" --> ClearCookies["모든 쿠키 삭제 (Max-Age=0)"]
        CheckRT -- "예" --> TryRefresh["AuthService.refreshAccessToken 시도"]
        
        TryRefresh -- "성공" --> SetCookies["새 AT/RT 쿠키 응답 설정 (Set-Cookie)"]
        TryRefresh -- "실패 (RT만료/오류)" --> ClearCookies
        
        CheckTime -- "아니오 (유효함)" --> Success["유저 UUID 추출 (opaqueId)"]
    end

    ClearCookies --> Fail401
    SetCookies --> Success
    Success --> Final["응답 헤더에 X-User-Id 설정 후 종료"]
Loading

imeasy99 added 4 commits March 5, 2026 14:44
- `JwtAuthenticationFilter` 리팩토링: 토큰 추출 방식 통합 및 중복 제거
- `/api/v1/auth/introspect` 엔드포인트 인증 필요 없이 접근 가능하도록 변경
- 만료된 토큰에서도 클레임을 안전히 조회할 수 있도록 내부 로직 확장
- 토큰 관련 예외 처리 및 유효성 검사 코드 간소화
- Access Token 만료 시 Refresh Token 기반 자동 재발급
- 새 토큰을 Set-Cookie 헤더로 반환
- 요청 토큰 탐색 우선순위 정의 (HttpOnly 쿠키 > Authorization 헤더)
- AT·RT 쿠키 만료를 위한 `clearAuthCookies` 유틸리티 메서드 추가
- `jwtProvider` 사용하여 남은 토큰 유효 시간 및 클레임 처리 로직 개선
- 요청 인증 중 예외 발생 시 쿠키 정리 및 상태 코드 401 반환 처리
- Authorization 헤더 방식 제거 및 HttpOnly 쿠키 적용
- AccessToken/RefreshToken 반환 방식을 HttpOnly 쿠키로 통일
- 클라이언트별 토큰 처리 순서 및 예외 로직 개선
- 불필요한 응답 헤더(X-Auth-Provider) 제거
- API 문서 수정: 새로운 토큰 처리 방식 반영
- SocialLoginController와 AuthController 코드 간소화 및 가독성 향상
@imeasy99 imeasy99 self-assigned this Mar 5, 2026
@imeasy99 imeasy99 added the 🍎 fix 기능 수정 label Mar 5, 2026
@imeasy99 imeasy99 requested a review from Dhani5703 March 5, 2026 09:03
@TwoMuchSilver TwoMuchSilver merged commit c5f627f into dev Mar 9, 2026
imeasy99 added a commit that referenced this pull request Apr 2, 2026
* feat: 서브도메인 통일위해 cors 설정 수정

* [Feature] 게이트웨이 서버 거치도록 변경 및 docker로 배포 방식 변경 (#60)

* chore: 추가 UUID 생성 라이브러리 의존성
* fix: 사용자 역할 관련 로직 제거 및 JwtProvider 리팩토링
- `Role` 사용 및 관련 로직 삭제
- `JwtProvider` 메서드 간소화 및 `UuidCreator`로 jti 생성 로직 변경
- `PrincipalDetails` 구조 단순화 (역할 제거)
- `AdminApi` 어노테이션 삭제
* fix: `Role` enum 및 관련 로직 제거
- `Role` 삭제 및 관련 애트리뷰트, 메서드 제거
- `UUID.randomUUID`를 `UuidCreator.getTimeOrdered`로 대체
- `JwtProvider` 호출 시 역할 매개변수 제거
* fix: 소셜 로그인 역할 제거

* feat: Gradle Wrapper 설정 추가
* feat: CommonResponse로 통합 및 불필요 클래스 제거

* feat: Dockerfile 추가 및 애플리케이션 컨테이너화
* feat: EC2 Docker 배포 문서 추가 및 프로젝트 이름 수정
* feat: EC2 배포 GitHub Actions 워크플로 개선
* feat: 프로젝트 이름 변경 및 환경 변수 수정
* feat: GitHub Actions 환경 변수 파일 처리 방식 개선
* feat: EC2 환경 변수 경로 및 배포 스크립트 개선
* feat: CORS 설정 제거 및 Gateway 위임 처리
* feat: redirectUri 지원 및 소셜 로그인 처리 개선
* feat: 배포 워크플로 브랜치 업데이트

* feat: 쿠키 기반 인증 기능 추가 및 기존 토큰 처리 방식 개선 (#61)

- `JwtAuthenticationFilter` 수정: HttpOnly 쿠키에서 accessToken 우선 추출하도록 개선
- CookieFactory 추가: AccessToken/RefreshToken 생성을 안전하게 관리
- CookieProperties 추가: 쿠키 설정값 분리 및 관리 용이성 향상
- 기존 ResponseCookie 생성 로직을 CookieFactory로 위임
- SocialLoginController 및 AuthController에서 토큰 처리 방식 리팩토링
- `application-dev.yml` 및 `application-prod.yml`에 쿠키 설정 값 추가

* [Fix] 토큰 재발급 로직 변경 (#62)

* fix: JWT 처리 방식 개선 및 인증 로직 확장

- `JwtAuthenticationFilter` 리팩토링: 토큰 추출 방식 통합 및 중복 제거
- `/api/v1/auth/introspect` 엔드포인트 인증 필요 없이 접근 가능하도록 변경
- 만료된 토큰에서도 클레임을 안전히 조회할 수 있도록 내부 로직 확장
- 토큰 관련 예외 처리 및 유효성 검사 코드 간소화

* feat: 토큰 introspect 엔드포인트 확장 및 사일런트 리프레시 지원

- Access Token 만료 시 Refresh Token 기반 자동 재발급
- 새 토큰을 Set-Cookie 헤더로 반환
- 요청 토큰 탐색 우선순위 정의 (HttpOnly 쿠키 > Authorization 헤더)
- AT·RT 쿠키 만료를 위한 `clearAuthCookies` 유틸리티 메서드 추가
- `jwtProvider` 사용하여 남은 토큰 유효 시간 및 클레임 처리 로직 개선
- 요청 인증 중 예외 발생 시 쿠키 정리 및 상태 코드 401 반환 처리

* feat: 배포 워크플로 브랜치 목록 수정

* feat: HttpOnly 쿠키 기반 인증 방식 리팩토링

- Authorization 헤더 방식 제거 및 HttpOnly 쿠키 적용
- AccessToken/RefreshToken 반환 방식을 HttpOnly 쿠키로 통일
- 클라이언트별 토큰 처리 순서 및 예외 로직 개선
- 불필요한 응답 헤더(X-Auth-Provider) 제거
- API 문서 수정: 새로운 토큰 처리 방식 반영
- SocialLoginController와 AuthController 코드 간소화 및 가독성 향상

* Revert "[Fix] 토큰 재발급 로직 변경 (#62)" (#63)

This reverts commit e388a92.

* [Fix] 토큰 재발급 로직 변경 및 로그인 시 토큰 쿠키에 담는 것으로 변경 (#64)

* fix: JWT 처리 방식 개선 및 인증 로직 확장

- `JwtAuthenticationFilter` 리팩토링: 토큰 추출 방식 통합 및 중복 제거
- `/api/v1/auth/introspect` 엔드포인트 인증 필요 없이 접근 가능하도록 변경
- 만료된 토큰에서도 클레임을 안전히 조회할 수 있도록 내부 로직 확장
- 토큰 관련 예외 처리 및 유효성 검사 코드 간소화

* feat: 토큰 introspect 엔드포인트 확장 및 사일런트 리프레시 지원

- Access Token 만료 시 Refresh Token 기반 자동 재발급
- 새 토큰을 Set-Cookie 헤더로 반환
- 요청 토큰 탐색 우선순위 정의 (HttpOnly 쿠키 > Authorization 헤더)
- AT·RT 쿠키 만료를 위한 `clearAuthCookies` 유틸리티 메서드 추가
- `jwtProvider` 사용하여 남은 토큰 유효 시간 및 클레임 처리 로직 개선
- 요청 인증 중 예외 발생 시 쿠키 정리 및 상태 코드 401 반환 처리

* feat: 배포 워크플로 브랜치 목록 수정

* feat: HttpOnly 쿠키 기반 인증 방식 리팩토링

- Authorization 헤더 방식 제거 및 HttpOnly 쿠키 적용
- AccessToken/RefreshToken 반환 방식을 HttpOnly 쿠키로 통일
- 클라이언트별 토큰 처리 순서 및 예외 로직 개선
- 불필요한 응답 헤더(X-Auth-Provider) 제거
- API 문서 수정: 새로운 토큰 처리 방식 반영
- SocialLoginController와 AuthController 코드 간소화 및 가독성 향상

* [Deploy] 알파 서버 분리 및 서버 이전 (#65)

* feat: 소셜 로그인 및 토큰 처리 로직 리팩토링

- OAuthClient 인터페이스 구현 정리 및 카카오/구글 OAuth 로직 통합
- id_token 파싱 추가로 사용자의 프로필 정보를 효율적으로 처리
- 사용자 로그인 응답 속도를 개선하기 위해 비동기적 로그인 시간 업데이트 도입
- RefreshToken 발행 및 관련 로직 간소화
- RestTemplate 구성 추가로 HTTP 통신 설정 통합
- 코드 가독성 및 유지보수성을 고려한 주요 메서드 리팩토링

* feat: 프로파일별 설정 분리 및 데이터베이스 설정 변경

* feat: PostgreSQL 전환 및 배포 프로세스 개선

- 프로젝트 데이터베이스를 MySQL에서 PostgreSQL로 전환
- Docker Compose 설정 삭제 및 환경 변수 샘플 파일 업데이트
- Gradle에 PostgreSQL 드라이버 및 HTTP 클라이언트 의존성 추가
- EC2 배포 워크플로 수정: 브랜치별 환경 변수 처리 및 Docker Run 방식 적용
- 기존 CORS 설정 초기화 및 Gateway를 통한 위임 구조 반영

* feat: 배포 워크플로 브랜치 리스트에 alpha 추가

* feat: 환경별 프로파일 설정 및 배포 워크플로 개선

- 운영, 알파, 로컬 환경별 Spring 프로파일 설정 추가
- SPRING_PROFILES_ACTIVE 기본값을 'local'로 변경
- GitHub Actions 배포 워크플로 환경 변수 처리 방식 간소화
- Docker Hub 및 EC2 관련 Secrets 활용으로 보안 강화
- PEM 키 처리 로직 개선 및 유효성 검증 추가

* feat: RestClient 구성 추가 및 기존 RestTemplate 제거

- Spring WebClient 기반 RestClientConfig 추가
- Kakao, Google, Naver OAuth 클라이언트에서 RestTemplate 제거 후 RestClient로 전환
- Spring Boot, Kotlin, HttpClient 등 주요 의존성 버전 업그레이드
- Gradle 설정 업데이트: Spring Boot 4 및 Kotlin 2.3 대응

* feat: Java 언어 버전 다운그레이드

* feat: JSON 데이터 처리 의존성 추가

- Spring Boot JSON Starter 의존성 추가
- JSON 처리 기능 개선 및 확장 준비 완료

* feat: `ObjectMapper`를 `JsonMapper`로 전환

* feat: EC2 배포 환경 설정 개선 및 워크플로 업데이트

- EC2 배포 기본 경로 설정(PROJECT_ROOT) 추가 및 환경변수 경로 명시

* feat: 배포 워크플로 환경 변수 설정 추가

* feat: 배포 워크플로 EC2 기본 경로 수정

- EC2 배포 경로를 명확히 설정하기 위해 PROJECT_ROOT 값을 절대 경로로 변경

* feat: GitHub Actions 배포 워크플로 운영 이미지 태그 변경

- IMAGE_TAG 값을 latest에서 prod로 수정
- 운영 환경(Spring 프로파일)과 이미지 태그 설정 일치하도록 개선

* feat: 배포 워크플로 docker-compose 명령어를 docker compose로 변경

- docker-compose 명령어를 최신 표준인 docker compose로 교체
- 배포 스크립트의 가독성 및 유지보수성 향상

* feat: 배포 워크플로 docker compose 명령어 업데이트

- docker stop 및 rm 명령어를 docker compose stop과 rm으로 변경
- `--force-recreate` 옵션 추가로 컨테이너 재생성 로직 개선

* feat: 소셜 로그인 응답 데이터 필드 기본값 추가

- GoogleUserInfoResponse의 `verifiedEmail` 필드 기본값을 `true`로 설정
- NaverUserInfoResponse의 `verifiedEmail` 필드 기본값을 `false`로 설정

* feat: Google OAuth `verifiedEmail` 필드 기본값 추가

- GoogleUserInfoResponse의 `verifiedEmail` 값이 null일 경우 기본값을 `true`로 설정하여 예외 방지

* feat: 프로젝트 환경 설정 및 의존성 업데이트

- Java 버전을 25로 업그레이드하고 관련 Gradle 설정 업데이트
- Gradle 및 Kotlin 플러그인 버전 업그레이드
- 로깅 설정 추가: Logback 구성(`logback-spring.xml`) 및 Spring 프로퍼티 적용

* feat: 로깅 및 Hibernate 설정 업데이트

- Hibernate `format_sql` 설정 값 false로 변경 (모든 환경)
- `org.hibernate.SQL` 로그 레벨을 warn에서 error로 변경 (prod 환경)
- Logback 설정 개선: 'service', 'env' 필드 자동 포함 처리
- local, alpha 환경에서 Hibernate SQL 로깅 추가 (JSON 형식)

* feat: 환경 설정 및 배포 워크플로 업데이트

- `application-prod.yml` 및 `application-alpha.yml` Hibernate 및 로깅 설정 조정
  - Hibernate `format_sql` 및 `use_sql_comments` 설정 추가
  - 로그 레벨 수정: prod 환경에서 `WARN` → `ERROR`, alpha 환경에서 `INFO` → `DEBUG`
- EC2 배포 워크플로 기본 경로(PROJECT_ROOT) 절대 경로에서 홈 디렉토리로 수정

---------

Co-authored-by: TwoMuchSilver <silver@easyappfactory.com>
Co-authored-by: Pokbab <xxxtintin@naver.com>
@imeasy99 imeasy99 deleted the fix/token-refresh branch April 6, 2026 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🍎 fix 기능 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants