안녕하세요 오늘은 웹 페이지를 설계함에 있어 대중적으로 쓰이는 OAuth 2.0 프로토콜에 대해 공부해보겠습니다 💪
우리가 웹 서비스를 개발할 때 인증 과정을 어떻게 구현할 것인가는 항상 중요한 문제가 됩니다.
인증은 보안에 있어서 가장 핵심적인 문제이기 때문에, 개발자 입장에서는 심혈을 기울여서 설계를 해야합니다 🤔
OAuth 는 이러한 개발자의 고민을 해결해줍니다.
OAuth 2.0(Open Authorization 2.0) 은 인증을 위한 개방향 표준 프로토콜 입니다.
요즘 우리가 사용하는 대다수의 웹 서비스는 로그인 시 외부 소셜 계정을 기반으로 간편하게 인증하는 인증 서비스를 제공합니다 🧑🏼💻
카카오, 구글, 페이스북 등 자신이 해당 플렛폼의 계정을 갖고만 있다면 손쉽게 로그인이 가능합니다.
이렇게 Third-Party 프로그램(우리가 개발하는 웹) 이 Client를 대신해 리소스 서버에서 제공하는 자원에 대한 접근 권한을 위임받는 방식을 OAuth 방식이라고 합니다 💡
이번 포스팅에서는 현재 가장 최신 버전인 OAuth 2.0을 기준으로 설명합니다 ❗️
OAuth 동작 원리를 본격적으로 알아보기 전에 관련 용어를 공부해보겠습니다.
1) Resource Owner
리소스 소유자를 말합니다.
여기서 리소스란 외부 소셜 서비스(API)를 이야기합니다.
즉 해당 플랫폼에서 리소스를 소유하고 있는 사용자를 의미합니다.
우리의 웹 서비스를 이용하는 유저를 의미하는거겠죠? 🙆🏻
2) Authorization Server
Authorization Server는 Resource Owner를 인증하고, 우리가 개발한 웹 서비스에게 Access Token을 발급해주는 서버입니다.
즉 외부 플랫폼 리소스에 접근할 수 있는지 인증을 하는 서버를 의미합니다 👨💻
3) Resource Server
구글,페이스북, 카카오와 같이 보호되는 리소스를 가지는 서버를 말합니다 ✅
4) Client
개인적으로 Client 라는 용어가 가장 이해하기 어려웠습니다.
Client란 Resource Owner 를 대신해 Authorization Server & Resource Server 에 접근하는 주체입니다.
우리가 개발하려는 서비스가 되겠죠?
우리가 개발하려는 서비스를 Client라고 정의한 이유는 우리 서비스가 Authorization Server & Resource Server 입장에서 클라이언트이기 때문입니다 ✔️
OAuth 2.0 동작 원리를 알아보기 전에 선행되어야 할 것이 있습니다.
우리가 개발하려는 웹 서비스(Client) 를 Resource Server 에 등록해야 합니다 🎮
이때 Redirect URI도 함께 등록해야 하는데, 해당 위치는 사용자가 OAuth 2.0 서비스에서 인증을 마치고 리다이렉션 시킬 위치입니다.
웹 서비스 등록을 성공적으로 마치면, Client ID 와 Client Secret 을 얻을 수 있습니다.
두 정보는 추후 Access Token을 획득하는데 중요한 역할을 함으로, 외부로 유출되어서는 안됩니다 ⛔️
해당 이미지는 OAuth 2.0 동작과정 시퀀스 다이어그램 입니다.
Resource Owner가 우리가 설계한 서비스의 '카카오로 로그인하기' 등의 버튼을 클릭해 로그인을 요청합니다.
Client는 OAuth 프로세스를 시작하기 위해 Resource Owner의 브라우저를 Authorization Server로 보냅니다.
Client는 이때 Authorization URL에 response_type, client_id, redirect_uri, scope 등의 매개변수를 쿼리 스트링으로 포함하여 보냅니다 🧑🏼💻
response_type : 반드시 code로 값을 성정해야 합니다.
인증이 성공할 경우 Client는 후술할 Authorization Code를 받습니다.
client_id : 웹 서비스를 Resource Server에 등록했을 때 발급받은 Client ID을 의미합니다.
redirect_uri : 웹 서비스를 Resource Server에 등록했을 때 등록한 redirect URI을 의미합니다.
scope : Client가 부여받은 리소스 접근 권한을 의미합니다.
Client 로부터 Authorization URL로 이동된 Resource Owner는 제공된 로그인 페이지에서 ID/PW을 입력하여 인증을 할 것입니다.
Authorization URL에서 인증이 성공했다면, Authorization server는 기존에 설정한 Redirect URL에 Authorization Code 를 포함하여 사용자를 리다이렉션 시킵니다.
Authorization code란 리소스 접근을 위한 Access Token을 획득하기 위해 사용하는 임시 코드이며, 수명은 매우 짧습니다 🧑🏼💻
Client는 다시 Authorization Server에 Authorization Code를 전달하고, Access Token을 발급받습니다.
Client는 자신이 발급받은 Resource Owner의 Access Token을 데이터베이스에 저장하고, 이후 Resource Server에서 Resource Owner의 리소스에 접근하기 위해 Access Token을 사용합니다 🧑🏼💻
Access Token은 절때 유출되서는 안됩니다 ⛔️
위 과정을 모두 성공적으로 마치면 Client는 Resource Owner에게 로그인이 성공하였음을 알립니다.
이제 Access Token을 가지고 접근 가능한 Resource 에 접근할 수 있습니다 🙌
이제 Access Token을 발급 받았기 때문에 정해진 Scope 내에서 다양한 리소스를 이용 할 수 있습니다 💡
앞에 설명한 OAuth 2.0 동작 원리에서 처음 로그인 요청시 scope를 정할 수 있다고 했습니다.
scope란 Client가 사용 가능한 Resource 접근 범위를 제한하는 것입니다.
예를 들어 구글 플렛폼을 Resource Server로 사용할 때, 사용자의 연락처를 받아오고 싶다면,
scope에 연락처 scope 문자열을 포함하여 서버에 요청하면 됩니다 💪
이러한 방식으로 발급된 Access Token은 Scope 정보를 가지고 있어 권한을 제한합니다 ❗️
우리가 개발하는 웹 서비스(Client)에서도 백엔드와 프론트엔드의 역할을 나누어야 합니다.
Client가 인증을 위해 Authorization URL을 통해 Authorization Server로 이동할 때 해당 URL은 누가 생성할까요? 🤔
백엔드 프론트엔드 어느곳에서나 생성해도 정상적인 동작에 지장은 없지만, Client ID , Scope와 같은 정보들은 백엔드 쪽에서 가지고 있기 때문에 응집도 측면에서 백엔드에서 생성하는것이 좋습니다 👍
이렇게 생성한 Authorization URL을 프론트엔드가 가져와 사용자를 Authorization Server로 리다이렉 시킵니다.
인증을 모두 마치면 지정한 Redirect URL로 돌아옵니다. 보통 Redirect URL 은 프론트쪽으로 설정합니다.
이때 Authorization Code와 함께 온다고 말했었죠?
Authorization Code를 받은 프론트엔드는 다시 해당 Code를 백엔드 API를 통해 백엔드 쪽으로 보냅니다.
그러면 백엔드는 Authorization Code, Client ID, Client Secret 등으로 Access Token을 받습니다 🧑🏼💻
[프론트 & 백 역할 정리]
Authorization URL 은 Client 백엔드가 생성한다.
Client 프론트단은 해당 URL을 리다이렉트 시켜 브라우저가 인증을 가능하게 하도록 한다.
인증 결과로 받은 Authorization Code는 Client 프론트단에서 받는다.
프론트단은 Authorization Code를 백단으로 다시 보낸다.
백단에서 Authorization Code와 더불어 다양한 정보로 Authorization Server 로부터 Access Token을 발급 받는다.
OAuth 2.0을 글로 정리했지만 사실 아직까지 찝찝한 구석이 있습니다.
추후 Spring을 이용해서 실제로 구현할 예정입니다 🧑🏼💻
OAuth2.0 개념 및 작동방식
OAuth 2.0 개념과 동작원리
OAuth 2.0 동작 방식의 이해OAuth 2.0 동작 방식의 이해|작성자 MDS인텔리전스