카테고리 없음

OAuth와 PKCE 플로우

노엠디엔 2024. 8. 17. 17:06

Next 팀프로젝트를 하며 로그인/회원가입 부분을 맡아 기능을 구현하면서
supabase를 사용하게 되었는데
Supbase는 OAuth2.0의 PKCE 플로우를 사용한다는 글을 보게 되었다.

그래서 이번에 OAuth2.0과 PKCE 플로우에 대해서 정리해보려고 한다!

 

https://supabase.com/docs/guides/auth/sessions/pkce-flow

 

PKCE flow | Supabase Docs

About authenticating with PKCE flow.

supabase.com

OAuth

Open Authorization의 약자로 인터넷 사용자들이 비밀번호를 제공하지 않고,
다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나
애플리케이션의 접근권한을 부여할 수 있는 공통적인 수단으로 사용되는,
접근 위임을 위한 개방형 표준이다.

 

단계  및 구성 요소
(Authorization Code Grant / 권한 부여 승인 코드 방식)

구성요소 역할 설명
Client(클라이언트) 권한 요청 Resource server에게 필요한 자원을 요청하고
응답하는 관계 사용자가 클라이언트 애플리케이션에
로그인하려고 하면, 클라이언트는 자원 소유자의
권한을 얻기 위해 Authorization Server에 권한을
요청하는데 이때 특정 서버(Naver, kakao등)에
로그인 페이지를 요청한다.
Authorization Server
(인증 서버)
사용자 인증 권한을 부여(인증에 사용할 아이템을 제공)하는 서버
인증 서버는 자원 소유자(사용자)에게 클라이언트가
요청한 권한을 부여할지 확인하기 위해 서비스 정보와
리소스 로그인 서버에 등록된 서비스 정보를 비교한다.
이후 로그인 화면을 제공하고,사용자는 ID,PW를 보내
Authorization  Code를 발급 요청 
Resource Owner
(자원 소유자)
권한 부여 웹서비스를 이용하려는 사용자,
자원(개인정보) 소유한자,
자원 소유자는 client가 사용하려는 기능(scrope)에
승인 하게되면
Resource Owner가 권한을
위임했다는 승인이 Resource Server에 전달된다.
Client에게 권한 승인을 했더라도 아직 Server가
허락하지 않은 상태라 Resource Server도
Client에게 권한 승인을 하기위해
Redirect URL을 통해 Authorization  Code
클라이언트에게 전달된다.
Client(클라이언트) 승인 코드 수신 클라이언트는 Authorization Server로부터
Authorization  Code 를 받아서,
Access Token 을 요청할 준비를 합니다.
Authorization Server
(인증 서버)
액세스 토큰 발급 클라이언트는 받은 승인 코드를 사용해 인증 서버에
액세스 토큰을 요청하고, 인증 서버는 클라이언트에게  Access Token(짧은 만료기간) 과 Refresh Token(긴 만료기간)을 함께 발급
필요없어진 Authorization code는 지워진다.
Client (클라이언트) 리소스 요청 클라이언트는 발급받은 Access Token을 사용해 Resource Server에 보호된 리소스에 접근할 수 있는 요청을 보냄
Resource Server
(리소스 서버)
리소스 제공 사용자의 개인정보를 가지고있는 애플리케이션 (Google, Kakao, Naver 등) 서버
redirect 경로를 통해서 Authorization code제공 
클라이언트가 제공한 액세스토큰을 검증하고,
유효한 경우 client를 구분하는 값(code) 를 전달

 

PKCE 플로우

사용자의 동일한 컴퓨터에 침입하는 악성 프로그램이
인증 코드(AccessToken, Client Id 등) 가로채는 것을 방지하기 위해
일회성 암호를 사용하는
Authorization Code Grant flow의 확장 버전이다.

PKCE의 일회용 검증 도구

  1. code_verifier:  Client가 생성해 둔 43~128 길이의 Random String입니다.
    a-z, A-Z, 0-9, -._~와 같은 문자가 포함된다.
  2. code_challenge_method : 해싱 알고리즘입니다. 대표적으로 SHA256, SHA512가 있다.
  3. code_challenge Base64url(code_challenge_method(code_verifier)).
  4. 즉, code_challenge는 code_verifier를 code_challenge_method로 해싱하고,
    이 값을 base64 url로 인코딩한 값이다.
  1. 코드 챌린지 생성 :
    • 클라이언트는 랜덤 하게 생성된 코드 베이스(code verifier)를 SHA-256 해시
      알고리즘으로 해시하여 코드 챌린지(code challenge)를 생성합니다.
    • 코드 챌린지와 해시 방법(예: "S256")을 포함하여 인증 요청을 보냅니다.
  2. 인증 코드 요청:
    • 사용자가 클라이언트 애플리케이션에 로그인하고 승인하면,
      인증 서버는 인증 코드를 클라이언트에 반환합니다.
  3. 코드 검증:
    • 클라이언트는 인증 서버에 다시 요청을 보내어 인증 코드를
      액세스 토큰으로 교환합니다.이 요청에는 원래의 코드 베이스가 포함됩니다.
    • 인증 서버는 클라이언트가 보낸 코드 베이스를 다시 해시하고
      초기 코드 챌린지와 비교하여 일치하면 액세스 토큰을 발급합니다.

 

Supabase에서 비밀번호 찾기 기능

팀 프로젝트에서 Supabase를 사용해서 비밀번호 찾기 기능을 구현하다
Supabase에서는 PKCE Flow를 사용한다는 내용을 보게 되었는데
(Supabase는 Oauth 2.0을 사용함).
사용자가 비밀번호 찾기 기능을 이용할 때, 가입한 이메일 주소로
비밀번호 초기화 페이지로 리다이렉트 되는 링크를 전송된다.
이 링크에는 일회성 토큰이 URL의 쿼리 문자열에 포함되며 토큰을 통해
Supabase에서 일화성으로 사용자의 세션을 부여한다.

 

사용자의 이메일 주소로 비밀번호 재설정 링크를 보내는 코드

  • email: 비밀번호를 재설정할 사용자의 이메일 주소
  • redirectTo: 사용자가 이메일의 재설정 링크를 클릭한 후 리다이렉션될 URL
    URL의 쿼리스트링에 Supabase에서 해당 사용자를 승인할 인증코드 포함(일회용).
const { data: resetPasswordData, error: resetError } =
await supabase.auth.resetPasswordForEmail(email, {
  redirectTo: redirectToUpdatePw,
});

resetPasswordForEmail로 현재 url에 쿼리스트링에 인증코드를 가져와
Supbase에서 일회용으로  해당 사용자에 대한 요청을 승인하는 코드

({ data: sessionData, error: sessionError } =
   await supabase.auth.exchangeCodeForSession(token));
  • token: 인증 서버에서 발급받은 인증 코드(code), 액세스 토큰을 요청합니다.
  • sessionData: 세션 교환이 성공했을 때 반환되는 데이터로,
    액세스 토큰과 리프레시 토큰이 포함됩니다.

 

 

참고블로그 : https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-OAuth-20-%EA%B0%9C%EB%85%90-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC


OAuth2 권한부여 방식 종류 블로그 : https://blog.naver.com/mds_datasecurity/222182943542

OAuth2.1의 등장과 PKCE 블로그: https://medium.com/@itsinil/oauth-2-1-pkce-%EB%B0%A9%EC%8B%9D-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-14500950cdbf

OAuth1.0의 흐름과 문제 블로그 : https://velog.io/@kimunche/OAuth2.0%EC%9C%BC%EB%A1%9C%EC%9D%98-%EC%97%AC%EC%A0%95