[FastAPI] 6. Google-auth 및 PyJWT를 이용한 OAuth2 인증 구현 1

반응형

이번 포스트에서는 인증에 대한 이야기를 해보고자 합니다. 

 

Spring에서는 Spring Security라는 모듈을 제공하여 개발자가 인증에 대한 구현을 개별적으로 하지 않고도 쉽게 구현할 수 있는 방법이 존재했습니다. 이를 통하여 Google 개발자 콘솔에서 Client ID를 미리 발급받은 후 구현되어 있는 구현체만 잘 사용하면 어렵지 않게 OAuth2 인증을 구현할 수 있었죠.

 

FastAPI도 이와 비슷하게 OAuth2 인증을 구현하지만 JWT를 사용하는 것에는 별도의 구현 처리를 해줘야 합니다. 이번 포스트에서는 이 두 라이브러리를 가지고 OAuth2 인증을 어떻게 구현할 수 있는지에 대해 알아보겠습니다.

 

 

[Spring boot] Spring boot Security로 시작해보는 인증

Spring Framework를 이용하여 웹 서비스나 REST API 서비스를 개발하게 되면 가장 필요로 하는 것은 바로 인증일 것입니다. 여기서 말하는 인증이란, 내가 개발한 서비스를 이용하기 위해 식별하고자

blog.neonkid.xyz

이 글을 읽어보시기 전에 OAuth2 인증에 대한 선행 공부를 추천합니다. 만약 OAuth2 인증을 처음 접해보시는 분들이라면  위 글을 먼저 읽어보시기 바랍니다.

 

 

 

 

 

To Be

먼저 우리가 구현하고자 하는 모습을 아키텍처 그림을 통해 나타내 봤습니다. 

Spring boot Security를 사용했을 때는 페이지가 있는 MVC를 기준으로 작성을 했지만 이번에는 Restful API를 이용해서 OAuth2 로그인을 구현하고자 합니다. 다른 점이 있다면 Redirect URL을 제공하지 않는다는 점이 있는데, 이 부분은 React나 Vue와 같은 SPA 개발 프레임워크 등을 이용해서 Google 로그인 Redirect URL을 지정하고, 해당 로그인을 통해서 받은 권한 부여 코드를 REST 서버로 요청하면 이에 JWT 토큰을 생성하여 Client에게 제공해주면 됩니다.

 

그런 다음 클라이언트는 해당 토큰을 이용하여 애플리케이션 서비스를 이용할 수 있도록 구현해주면 됩니다.

 

Spring boot Security에서는 이러한 과정들이 전부 구현되어 있지만 공교롭게도 FastAPI에서는 이러한 과정을 전부 수동으로 구현해줘야 합니다.

 

이를 위해서 우리는 JWT가 무엇인지 간단하게 알고 넘어가야 합니다.

 

 

 

 

JWT

JWT는 웹 표준(RFC 7519)으로써 JSON 객체를 이용한 가볍고 자가 수용적인 방식으로 정보를 전달하는 토큰입니다. 따라서 아래와 같이 JSON 구조로 되어 있는 인증 포맷입니다.

위 구조는 JSON 형태만을 보여준 것이며 실제 이 데이터는 JWT에서 payload에 해당 됩니다. payload가 무엇이냐구요? 아마 컴퓨터 네트워크를 공부해보신 분들이라면 네트워크의 패킷 구조에 대해 알고 계실 것입니다. 패킷 구조는 기본적으로 Header와 data로 구분되는데, JWT 역시 Header와 Payload로 구분되어 지며 payload는 여기서 패킷의 data에 해당되는데요. 이 부분은 2편에서 좀 더 심층적으로 어떻게 사용할 수 있는지 알아보기 위해서 잠시 담아두도록 하겠습니다.

 

따라서 우리는 이러한 인증 정보를 JSON 형태로 담아둔 뒤 불러왔을 때 누구의 정보인지, 유효기간은 얼마나 되는지를 확인하여 인증을 수행할 수 있습니다.

 

 

 

 

Generate Client ID (Google)

우리는 여기에서 Google 인증 구현을 시도해볼 것입니다. 그러기 위해선 Google에서 Client ID를 발급받아야 하는데요. 만약 발급하지 못했다면 아래의 글을 참고하여 Google의 Client ID를 발급받아주세요.

 

 

[Spring boot] Spring boot Security를 이용한 OAuth2 인증 구현 1 - Google 계정 인증

지난 포스트에 이어서, 오늘은 새로운 프로젝트를 생성하여 Spring boot Security 디펜던시를 이용해 OAuth2 인증을 구현하는 시간을 가져보고자 합니다. 지난 포스트에서 OAuth2 인증을 구현하기 위해

blog.neonkid.xyz

 

 

 

 

Install Dependency

이제 본격적으로 구현을 해보도록 하죠. 먼저 JWT를 만들기 위한 PyJWT와 Google 인증 서버로의 인증 구현이 되어 있는 google-auth 디펜던시를 설치하도록 합니다.

FastAPI를 사용할 것이기 때문에 미리 FastAPI도 같이 설치해주면 좋겠죠?

 

 

 

 

Generate Token

먼저 토큰을 발급받는 부분부터 구현해볼텐데요. 우리가 토큰에서 사용해야할 정보는 바로 구글 계정의 정보입니다. 누가 우리 서비스에 접근하려는 거긴 한데, Google 계정으로 로그인 하였긴 했지만 그게 누구인지를 확인해야되는데요. 그래서 REST API에서는 Client에서 Redirect로 접속하여 받은 토큰을 받아 Google 계정 서버로 이 토큰을 넘겨주게 되면 어떤 Client ID로 이 토큰을 받았고, 누구의 정보인지를 확인할 수 있습니다.

 

조금 어려운 부분이라고 생각되어, 그림으로 한 번 더 그려봤습니다.

 

사용자가 웹 페이지에 접속해서 Google 로그인을 요청할 경우 위에서 입력한 Redirect URI로 요청을하게 되며 Google에서는 로그인 페이지를 보여주게 되고, 사용자가 정보를 입력하면 이를 Google에서는 인코딩된 JWT 토큰을 웹에 전달하며 웹에서는 다시 이를 백엔드로 전송하여 백엔드가 이 유저를 판단할 수 있도록 하는 구조입니다.

 

이를 코드로 정의하면 다음과 같습니다.

웹으로부터 받은 토큰을 ${token}이라고 가정했을 때 FastAPI에서 해줘야하는 부분은 이 인코딩된 토큰을 디코딩하여 payload로 받게 되는데, 이 때 주는 정보는 여러가지가 있지만 대표적으로 어떤 Client ID로, 누가 접근했는지를 알 수 있습니다.

 

우리는 이를 토대로 아래의 형식의 토큰을 만들어 반환해주는 API를 만들어주도록 하겠습니다.

기본적으로 토큰이 언제 만들어졌는지, 언제까지 사용할 수 있는지와 누구의 토큰인지를 알 수 있도록 4개의 구조를 마련하였습니다.

 

 

 

 

Create API

그럼 위의 정보를 토대로 API를 만들어보도록 하겠습니다.

POST 메소드를 이용하여 JSON에 id_token이라는 key로 구조를 삼고, 클라이언트가 요청했을 때 id_token 값에 Google에서 받은 JWT 토큰을 넣어서 백엔드가 확인할 수 있도록 구현해줍니다.

 

그리고 우리는 위에서 만든 구조를 바탕으로 'secret' key를 이용하여 base64로 인코딩한 값을 반환해주면 해당 값을 이용하여 클라이언트가 인증이 필요한 백엔드 엔드포인트를 호출할 수 있도록 할 수 있습니다.

 

여기서 주의할 점은 payload에서 datetime을 사용하는 key의 경우 exp와 iat가 있습니다. 만약 두 개의 키가 아닌 다른 키에 string이 아닌 datetime을 사용하는 경우 파싱 오류가 발생하므로 반드시 유효기간을 명시할 떄는 exp와 iat 키를 사용하여 인코딩하도록 합시다.

 

 

 

다음 포스트에서 인코딩하여 받은 토큰을 어떻게 사용할 수 있는지에 대해 알아보도록 하겠습니다.

반응형
comments powered by Disqus

Tistory Comments 0