pkce_thumbnail

기존의 OAuth 2.0을 보완하기 위한 여러 시도가 있습니다. 그 중 PKCE 그리고 더 발전된 형태인 OAuth 2.1에 대해 간략히 알아보겠습니다.

PKCE (Proof Key for Code Exchange)

PKCE는 악의적인 애플리케이션이 인증 코드를 가로채는 것을 방지하는 방법에 대한 내용입니다.

OAuth 2.0 인증과정 중 Authorization code가 탈취

OAuth 2.0의 흐름 중 다음과 같은 과정이 있습니다.

  1. Resource Owner(사용자)는 Authorization Server에 대한 인증을 진행
  2. 인증되면 Authorization Server는 Resource Owner(사용자)의 에이전트(브라우저)에게 redirect와 함께 Authorization code를 전달
  3. 에이전트(브라우저)에서 받은 Authorization code를 Client에게 전달
  4. Client는 Authorization code와 Client ID, Client Secret을 제출하여 Access Token을 발급받음.

여기서 문제는 Authorization code가 탈취되어 다른 Client에서도 사용할 수 있다는 점입니다.

3-1. 에이전트(브라우저)에서 받은 Authorization code를 악의적인 Client에게 전달 4-1. 악의적인 Client는 Authorization code와 탈취한 Client ID, Client Secret을 제출하여 Access Token을 발급받음.

PKCE의 원리

그럼 공격을 방지하려면 요청을 시작한 앱만이 액세스 토큰을 요청하고 얻을 수 있도록 해야 합니다.

PKCE는 “보증 키” 개념을 도입하여 이 문제를 해결합니다.

“보증 키”는 다음 3개로 구성됩니다.

  • code_verifier: random한 문자열을 생성
  • code_challenge: code_verifier를 해시 함수에 적용한 값
  • code_challenge_method: 해시 함수 메서드

PKCE 절차

추가된 PKCE 절차를 중심으로 나열해보겠습니다.

  1. (PKCE 절차) code_verifier를 생성하고 code_challenge를 생성
  2. (PKCE 절차) code_challenge와 code_challenge_method를 Authorization Server에 제출
  3. 사용자가 Authorization Server에 인증 진행.
  4. 사용자의 인증이 완료되면 사용자의 브라우저는 redirect_url로 redirect되고 Client 서버로 Authorization code 전달
  5. (PKCE 절차) Client 서버는 Authorization code와 code_verifier를 제출하여 Access Token을 발급받음
  6. Access Token 사용…

pkce_flow

PKCE reference

https://www.rfc-editor.org/rfc/rfc7636

https://oauth.net/2/pkce/

https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce

https://devocean.sk.com/blog/techBoardDetail.do?ID=166255&boardType=techBlog

https://sabarada.tistory.com/263

https://blog.logto.io/ko/how-pkce-protects-the-authorization-code-flow-for-native-apps

https://bluecheat.medium.com/oauth-2-1-pkce-%EB%B0%A9%EC%8B%9D-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-14500950cdbf

https://velog.io/@darren-kk/OAuth2.0%EA%B3%BC-PKCE

OAuth 2.1

이어서 2025년 9월 현재 IETF에서 논의중인 OAuth 2.1에 대해 간단히 알아보겠습니다.

OAuth 2.1은 OAuth 2.0를 개선한 프로토콜입니다.

주요 변경점

  1. PKCE는 Authorization Code Flow를 사용하는 모든 OAuth 클라이언트에서 필수 • 이제는 SPA나 네이티브 앱뿐 아니라, 서버 앱도 Code Flow를 쓴다면 무조건 PKCE 사용이 요구됩니다.
  2. Redirect URI는 문자열을 정확히 일치시켜야 함 • 기존에는 일부 느슨한 매칭(프리픽스 등)이 허용되었는데, 이제는 정확한 문자열 비교만 허용됩니다.
  3. Implicit Grant(response_type=token)는 더 이상 스펙에서 제외됨 • 보안상의 이유로, 토큰을 직접 브라우저로 전달하는 암시적 플로우는 사용하지 않습니다.
  4. Resource Owner Password Credentials Grant(ROPC)는 제외됨 • 사용자 비밀번호를 직접 애플리케이션에 입력받아 토큰을 교환하는 ROPC 방식은 더 이상 허용되지 않습니다.
  5. Bearer 토큰은 URI 쿼리스트링으로 전달 불가 • 토큰은 반드시 Authorization 헤더 등 안전한 방식으로만 전달해야 하며, URL 쿼리 파라미터로 넣는 건 금지입니다.
  6. 퍼블릭 클라이언트의 Refresh Token은 ‘발급 시 제약(sender-constrained)’ 또는 ‘1회용(one-time use)’이어야 함 • 퍼블릭 클라이언트(SPA, 모바일 앱 등)는 Refresh Token 탈취 위험이 크므로, 반드시 바인딩(예: DPoP, MTLS)하거나 1회만 쓰고 새로 발급받아야 합니다.
  7. Public/Confidential 클라이언트 정의가 단순화됨 • 더 이상 복잡한 조건 없이, 클라이언트가 비밀(Client Secret) 자격 증명을 가졌는지 여부로만 구분합니다.

OAuth 2.1 reference

https://oauth.net/2.1/

https://tech.kakaopay.com/post/spring-oauth2-authorization-server-practice/

https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/