Codong's Development Diary RSS 태그 관리 글쓰기 방명록
보안 (1)
2022-01-16 01:25:29

🙌 개요


웹 개발을 하면서 유저가 있다면 인증이라는 개념은 절대 빠지지 않는다. 하지만 매번 토이 프로젝트와 같이 소규모로 시작하는 경우 매번 인증을 직접 구현하기에는 너무 소요가 크다는 생각이 든다.

그러다 네이버, 카카오, 구글 등 다른 사이트 아이디를 통해 로그인이 가능한 것들을 보면서 어떻게 이런 것이 가능하지? 라는 의문을 가지게 됐다.

관련해서 검색을 하다보니 OAuth2.0 이라는 개념을 접하게 되었고, 단순히 social login을 사용하기 전에 이것을 알고 가야겠다는 생각이 들었다. 그래서 OAuth2.0에 대한 내용을 간략하게 정리해보려고 한다.

제 글만으로 부족할 수 있으니 references 내용들 꼭 읽어보시는 것을 추천드립니다 😅


OAuth2.0


🧐 OAuth2.0 이란?

OAuth2.0에 대한 rfc 문서 : https://datatracker.ietf.org/doc/html/rfc6749
정리를 잘해둔 한컴인텔리전스 블로그가 있어서 참고하여 작성하였다.

OAuth2.0은 rfc 문서의 제목에서 Authorization Framework이라 지칭된다. 핵심은 Third-Party 프로그램에게 리소스 소유자(Resource Owner)를 대신하여 리소스 서버(Resource Server)에서 제공하는 자원에 대한 접근 권한을 위임하는 방식을 제공한다.

뭐가 좋아서 쓰는 걸까?

큰 장점으로 단순성을 꼽을 수 있다. 구현자의 관점에서 볼 때 OAuth 2를 이용한다면 네이버나 카카오 등 다른 사이트 로그인을 통해 인증을 하고 접근 권한을 얻는 것이므로, 복잡한 인증 절차를 직접 구현하고 제공할 필요가 없어진다.

리소스 소유자는 뭐고 리소스 서버는 뭐지?

여기서 나오는 역할들에 대해 정리하고 넘어가자.

  1. Resource Owner : 리소스 소유자 또는 사용자. 보호된 자원에 접근할 수 있는 자격을 부여해 주는 주체. 즉 id/password를 입력하는 사용자가 된다. 인증이 완료되면 권한 획득 자격(Authorization Grant)을 Client에게 부여합니다.
  2. Client : 보호된 자원을 사용하려고 접근 요청을 하는 Application (ex. 내 fastapi server)
  3. Resource Server : 사용자의 보호된 자원을 호스팅하는 server (ex. 구글, 네이버, 카카오 등)
  4. Authorization Server : 권한 서버. 인증/인가를 수행하는 서버로 클라이언트의 접근 자격을 확인하고 Access Token을 발급하여 권한을 부여하는 역할을 수행 (ex. 구글, 네이버, 카카오 등)

지금까지의 핵심은 내 fastapi 서버는 사용자가 authorization server(ex. 네이버)에 인증하도록 하고, 인증 완료 시 권한을 얻어 Resource Server(ex. 네이버)에서 로그인한 사용자 정보를 얻어 내 서비스에 이용하면 된다.

권한을 얻었는 지 어떻게 알지?

인증에 성공하면 authorization server가 Access token / Refresh token(Optional)을 발급해준다.

이것들은 뭐냐.. 간단히 말하자면 Access token은 Resource Server(ex. 네이버)에게서 사용자의 보호된 자원을 획득할 때 사용되는 만료 기간이 있는 token이고, Refresh token은 Access token 만료 시 이를 갱신하기 위한 용도로 사용하는 token이다.

네이버와 카카오의 경우 Access Token의 만료 기간은 1~2시간 정도이다. Refresh Token의 경우 둘 다 존재하고 카카오는 기간이 몇 달 정도 되지만, 네이버는 딱히 명시되어있지 않았고, 응답에도 만료기간이 없는 듯했다..?(Refresh token 만료기간 관련 네이버 문의 링크 네이버 형...! 답 좀 달아줘라...)

자 이제 본격적으로 도식화된 그림을 통해 전체 흐름을 살펴보고 이해해보자.

🔁 OAuth2.0의 전체적인 흐름

흐름을 보기에 앞서 OAuth 프로토콜에서는 다양한 클라이언트 환경에 적합하도록 권한 부여 방식에 따라 4가지 종류로 구분해서 제공한다.

  1. Authorization Code Grant : 권한 부여 승인 코드 방식
  2. Implicit Grant : 암묵적 승인 방식
  3. Resource Owner Password Credentials Grant : 자원 소유자 자격증명 승인 방식
  4. Client Credentials Grant : 클라이언트 자격증명 승인 방식

그중에서 1번 Authorization Code Grant 방식이 자체 생성한 Authorization Code를 전달하는 방식으로 많이 쓰이고 기본이 되는 방식이기에 이것만 다루도록 하겠다. (네이버, 카카오 둘 다 이 방식을 사용함.)

이미지 출처 : https://darutk.medium.com/diagrams-and-movies-of-all-the-oauth-2-0-flows-194f3c3ade85

그림의 순서대로 내가 이해한 것을 네이버 로그인을 fastapi서버로 구현한다는 느낌으로 다음과 같이 가정하에 설명해보겠다.

그림에서 App XYZ = 내 앱 서버(fastapi)
그림에서 service ABC Authorization server = 네이버 인증 서버
그림에서 service ABC Resource server = 네이버 리소스 서버

  • 1~5 사용자가 내 앱에서 제공된 로그인 페이지에 있는 네이버 아이디 로그인 버튼을 누른 후, 네이버 로그인 페이지가 뜨면서 ID/PW로 로그인을 진행한다.
  • 6 네이버 인증 서버가 ID/PW가 유효한 것이 확인되면, 내 서버에 인증 코드(authorization code)를 보내준다.
  • 7~8 내 서버에서 받은 인증코드로 네이버 인증 서버에 Access token 발급을 요청하여 발급받는다.
  • A~D 발급받은 Access token으로 사용자 정보를 가져온다.

내 설명이 맞지 않거나 이해가 안 될 수 있으니 rfc 문서의 해당 부분을 링크로 달아둘 테니 확인해보길 바란다. 4.1. Authorization Code Grant

rfc 문서의 그림을 보고 느낀 것인데, 위의 그림에서 1번 부분의 App XYZ는 rfc 문서에서 user-agent인 것 같고, 이후 6번에 나오는 App XYZ는 rfc 문서에서는 Client이지 않나 생각이 든다.

위 그림에서는 하나의 App XYZ로 표현을 했지만 혼란을 방지하기 위해 user-agent와 client로 따로 표현됐어야 하는 것이 아닌가 싶다. 여기서 말하는 App XYZ가 결국 하나의 application을 말하는 것이므로 frontend/backend를 전부 포함한 개념이라 생각하면 맞는 말 같기도 하고 잘 모르겠다.. 나만 혼란스럽나..?


👏 마무리


핵심 정리

OAuth2.0의 핵심은 자원에 대한 접근 권한을 위임하는 방식이라는 것 같다.

즉 내 app이 있고, 사용자가 있다고 할 때, 사용자가 자신의 데이터에 대한 access 권한을 부여해주는 것 같다. 그 과정에서 사용자와 내 app 사이에 네이버나 카카오와 같은 인증 서버가 중개를 해주는 것이다.

그 결과 나는 app을 개발할 때 인증을 구현할 필요가 없으므로 비즈니스 로직에 좀 더 집중할 수 있다는 것이다.

마무리 멘트

좀 더 디테일하게 들어가자면 빼먹은 내용이 많겠지만, 우선 컨셉을 알아가는 것을 목적으로 글을 써봤다. 앞으로 남들이 다 쓰니까 쓴다는 이유 말고, 정확히 왜 쓰는 건지, 어떤 이점이 있는지 알고 쓸 수 있도록 노력하자.

references