Skip to content

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

Merged
imeasy99 merged 4 commits intodevfrom
fix/token-refresh
Mar 5, 2026
Merged

[Fix] 토큰 재발급 로직 변경#62
imeasy99 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 merged commit e388a92 into dev Mar 5, 2026
imeasy99 added a commit that referenced this pull request Mar 5, 2026
imeasy99 added a commit that referenced this pull request Mar 5, 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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant