카카오 로그인 연동 문의 드립니다

안녕하세요. 카카오 싱크를 이용해서 간편 로그인을 구현하려고 하고 있습니다.
시스템 설계를 하는 과정에서 어떻게 설계를 하는게 맞는 것인지 문의 드립니다.

질문 1 - 아래와 같은 구조로 설계를 하는 것이 맞는가?

image

  • Resource owner : 고객
  • User-Agent : 웹 브라우저 or 네이티브 앱 (iOS, AOS)
  • Server : 자체 백엔드 서버
  • Authorization Server : 카카오 인증 서버 (카카오 싱크)

질문 2 - state 생성 주체는 누구 인가?

대부분의 자료에서 client 에서 state를 생성 한다고 나와있는데요. 여기서 말하는 client가 client frontend & client backend 를 통칭하는 것인지 client frontend 를 칭하는 건지 모호해서 문의 드립니다.

질문 3 - state 검증 주체는 누구 인가?

csrf token 검증은 프론트에서 하려면 의미가 없을거 같은데 혹시 방법이 있을까요??

일단 백엔드에서 처리하는 방법을 한번 생각해 보았습니다. (실제 동작하는지는 검증이 안됐습니다.)

  • 고객이 카카오 로그인 버튼을 클릭한다.
  • 프론트에서 백엔드 서버로 요청을 한다.
    • 요청
      GET /oauth/authorization/kakao
      
      Host: localhost:8080 <- 백엔드 서버로 요청
      
    • 응답 (이때 state를 생성하고 쿠키에 담아서 리다이렉트 응답)
      HTTP/1.1 302 Found
      
      Location: https://kauth.kakao.com/oauth/authorize?client_id=1&redirect_uri=https://localhost:8080/oauth2/callback/kakao&response_type=code
      Set-Cookie: state=123456
      
  • 프론트에서 응답받은 리다이렉트 주소인 https://kauth.kakao.com/oauth/authorize?client_id=1&redirect_uri=https://localhost:8080/oauth2/callback/kakao&response_type=code 로 요청
  • 카카오 로그인 팝업 출력
  • 고객에 로그인
  • 카카오 로그인이 완료되면 302 응답
    • 응답
       HTTP/1.1 302 Found
    
       Location: https://localhost:8080/oauth2/callback/kakao?code=111111&state=123456
       ```
    
  • 프론트에서 백엔드 서버로 리다이렉트 (이게 맞는지도 궁금합니다.)
  • 백엔드 서버에서 query string (state) 와 쿠키 (state) 값 비교
  • 통과하면 인증 토큰으로 access token 발급
  • access token 으로 회원 정보 조회
  • 조회된 회원 정보를 통해서 자사 고객 정보와 매핑

질문 4 - 프론트에서 state 검증을 하게 된다면 어떻게 할 수 있는가?

인터넷을 찾아보니 프론트(웹 브라우저 or 네이티브 앱)에서 authorization code를 발급 받고 백엔드에서 Access Token 을 발급 방식을 많이 설명하고 있는데 이 방식으로 할 경우 csrf 공격을 어떻게 방지하는지 궁금합니다.

감사합니다.

안녕하세요~

질문 1 - 아래와 같은 구조로 설계를 하는 것이 맞는가?

넵. Backend가 분리되어 있는 경우 그렇게 처리들 하십니다.

질문 2 - state 생성 주체는 누구 인가?

state는 인가 요청 시 전달 한 값을 인가 처리 후, 리다이렉트 URI로 전달 받을 수 있는 파라메터입니다.
생성 주체가 따로 정해져 있지 는 않습니다.
(backend에서 난수 발급 받아 리다이렉트 URI에서 발급 받은 난수가 맞는지 backend로 검증 요청하는 경우도 있습니다.)

csrf 공격을 방지하기 위해 난수를 생성하고, 리다이렉트 URI에서 난수를 검증 하는 형태로 사용하신다면,
리다이렉트 URI에서 전달받은 state값이 인가 요청 시, 전달한게 맞는지 검증만 할 수 있으면 됩니다.
(csrf 공격을 방지용이 아니라 단지, 요청 URL 확인용으로 사용하는 경우도 많습니다.)

질문 3 - state 검증 주체는 누구 인가?

네, 기재해주신 내용 크게 문제는 없어보입니다. Redis같은 캐시 서버에 저장하거나 Server Context 에 저장하기도합니다.

state 생성시점 세션ID와 난수를 pair로 저장하고 리다이렉트 URI 전달 받은 난수로 조회하여 세션ID가 일치하는지 검증하기도 하지만, 리다이렉트 URI에서 전달 받는 인가 코드가 토큰 발급에 1회만 사용가능하므로 간단히 처리해도 문제 없을 것 같습니다.


백엔드로 리다이렉트 하는 경우도 있습니다. 처리 후, 프론트 페이지로 다시 리다이렉트 하는 형태로 …

질문 4 - 프론트에서 state 검증을 하게 된다면 어떻게 할 수 있는가?

csrf 공격방지는 인가 요청자와 토큰 요청자가 동일한지 판단하는 목적이라 생각하시면 됩니다.

인가 요청 시, 난수를 발급받아 인가 요청자를 특정하고
리다이렉트 URI에서 검증 후, 전달 받은 authorization code로 Access Token 을 조회 하는 것으로
질문3에 기재해주신 것처럼 구현하시면 됩니다.

감사합니다.

좋아요 1

길고 두서없이 질문을 드렸는데 답변해 주셔서 감사합니다.
덕분에 막막했던 의문점들이 많이 해소된거 같습니다.

감사합니다.

좋아요 1