소셜 로그인을 진행하기 앞서, 기본이 되는 OAuth 프로토콜을 알아보고 정리하는 시간을 갖기 위해 포스트를 작성하였다.
개념을 한 줄 요약하자면 "OAuth는 인가 과정에서, '인증'을 서비스에서 분리하는 과정이다."
1. OAuth 란?
우선 OAuth는 Open Authorization의 약자로, 이를 직역해보면 "권한 열기"이다.
구글, 애플, 카카오톡과 같은 여러 플랫폼의 사용자 데이터에 접근하기 위해, 제 3자 클라이언트(우리의 서비스)가 사용자의 접근 권한을 위임받을 수 있는 표준 프로토콜이다.
plus. 지금 글을 작성하고 있는 tistory도 카카오 OAuth를 사용하고 있다.
등장배경
OAuth 이전에는, 사용자의 아이디/비밀번호를 직접 제 3자 서비스에 제공해야 했다.
(예를 들어 Github에서 Google 계정과 연동을 하려면, Google 계정 정보를 Github에 직접 등록했어야 했다..)
이러할 경우 제 3자 서비스가 사용자의 모든 권한을 가지게 되고, 서비스의 계정 정보의 해킹 위험 또한 매우 높았다.
물론 이런 문제를 해결하기 위해서 구글은 AuthSub, 야후는 BBAuth 등 각 회사가 개발한 프로토콜이 있었지만, 표준화 된 방법이 아니었기 많은 불편함이 있었다.
이러한 배경 속에서 2007년에 OAuth 1.0 버전으로 처음 등장했다.
하지만 클라이언트의 구현이 매우 복잡했고, CSRF 공격에 대해 취약했으며, 모바일 환경에서의 구현이 어려웠다.
이후 더 단순하고 안전한 인증 구조를 제공하기 위해 OAuth 2.0이 개발되어 현재까지 많은 서비스에서 표준으로 채택되어 사용되고 있다.
2. OAuth 구성 역할
유저 | 서비스 | 플랫폼(구글, 애플, 카카오..) | |
Resource Owner | Client | Authorization Server | Resource Server |
인증을 수행하는 주체 | 권한을 위임받는 주체 | 인증을 수행하고 권한을 부여하는 주체 |
인가를 수행하고 리소스를 제공하는 주체 |
3. OAuth 주요 용어
"인증/인가"는 Security를 공부하면 처음으로 마주하는 개념이다.
어려운 개념은 아니나, 중요한 개념으로 이름이 비슷해 헷갈릴 경우가 있어 간략히 개념을 정리한다.
Authentication | 인증. 올바른 유저인지 확인하는 과정이다. |
Authorization | 인가. 인증된 유저에게 접근 권한을 부여하는 과정이다. |
[OAuth Setting]
Client_ID / Client_Secret | 클라이언트 자격증명 클라이언트가 권한 서버에 등록하면 발급받을 수 있으며, 권한 서버에서 클라이언트의 검증에 사용된다. |
Redirect URI | 클라이언트의 인증을 마치고, 권한 서버가 응답을 보낼 url |
[OAuth Request/Response]
Authorization Code | 인가 서버에서 인증 이후에 발급되는 코드 access token과 refresh token을 얻는 데 사용된다. |
Scope | 클라이언트가 유저 리소스에 대해서 특점 범위의 엑세스 권한을 요청하는데 사용된다. (예를 들어, 유저의 이름과 이메일 정보에 대한 권한 요청할 수 있다.) |
State | CSRF 공격에 대비하기 위해 클라이언트가 권한 서버에 요청 시 포함하는 임의의 문자열 권한 서버는 응답 시 동일한 값을 클라이언트에게 보내야 한다. |
Access Token | 클라이언트가 유저 리소스에 접근하기 위한 권한을 부여받은 토큰 |
Refresh Token | access token이 만료된 후 새로운 access token을 발급받기 위한 토큰 |
4. OAuth 동작 과정
OAuth 동작 과정은 위에 작성한 플로우로 충분히 설명이 될 것 같다.
추가로 플로우를 직접 그리면서 한 번 짚고 넘어가면 좋을 것 같은 주제들을 적어본다.
1) 인증 참여 주체
OAuth 인증 과정 수행에서 Resource Owner와 Authorization Server만 참여하고 있다.
Client는 사용자 정보에 대해서 알 필요가 없으며, 알아서도 안 된다.
2) OAuth와 서비스의 연결 시점
사실 OAuth와 서비스의 연결 시점은 완벽하게 동작되고 있는 '운영 Client'의 입장에서는 그렇게 중요하지는 않다. 하지만 OAuth 로그인을 개발 중인 시점에서 "OAuth 인증/인가는 문제 없이 잘 되었지만, Client 서버에서 문제가 생겨 회원가입에서 문제가 생겼다면?" 에서는 알아두면 좋을 것 같다.
아래 플로우에서는 9번 과정에 해당된다.
Client가 인가코드로 access token 요청 시점에, 인가된 유저일 경우 Client-OAuth 사이에 연결이 되었음을 의미한다. 이 시점은 사실 OAuth 플랫폼이 어떻게 구현하느냐에 따라 달라지는데 5~6번 사이의 시점에서 연결이 될 수 있다.
실제로 애플 로그인은 5~6번 사이의 시점에서 연결이 된다.
이러한 경우에 Access token 요청에서 에러가 생겼을 시, 테스트 계정 관리에 들어가서 연동 해지를 해야만 회원가입 환경을 일정하게 만들 수 있다. 특히, 애플의 경우는 사용자가 회원가입 한 시점에만 '사용자 이름' 정보를 주기 때문에, 이름이 반드시 필요한 경우에는 반드시 해지해야 한다.
3) 로그인 세션 응답
마지막에 Client 서버가 회원가입/로그인을 성공적으로 마치고, 반환하는 세션 응답은 구현에 따라 달라질 수 있다. 서비스 보안 방식이 세션 DB를 사용하는 방식이라면 세션 ID를, 서비스 자체적으로 생성한 Jwt을 사용한다면 Jwt을, OAuth Access/Refresh Token을 사용한다면 token(JWT X)을 반환할 수 있다.
4) 로그인 완료 이후, 리소스 요청
로그인을 마치고 사용자가 서비스를 이용하던 중, 리소스를 요청하는 경우를 생각해보자.
이는 '로그인 세션 응답'에 따라서 달라질 수 있다.
OAuth token을 사용한다면, OAuth Resource Server에서 리소스를 제공받을 수 있다.
그렇지만 세션 ID나 자체 Jwt을 사용한다면 그럴 수 없다.
하지만 조금만 생각해보면, '사용자가 리소스를 요청할 때마다 Resource Server에 요청을 보내서 받아오는 것이 좋은 방법일까?' 하는 의문이 생긴다. 그래서 회원가입 때 서비스에서 필요한 사용자의 Resource를 모두 받아와 서비스 DB에 저장하고, 리소스 요청 때마다 서비스 DB에서 조회하는 방식이 더 좋은 설계이지 않을까 생각한다.
5. OpenID Connect
OAuth 2.0에서는 Open ID Connect 의 개념이 도입됐다.
인증 서버는 똑같고, AccessToken과 더불어 ID Token의 발급 요청을 받는 것이다.
애플 소셜 로그인에서는 Open ID Connect 방식으로 동작한다.
(추가 정리 예정..)
참고
테코톡 (인증/인가, OAuth 2.0)
https://www.youtube.com/watch?v=y0xMXlOAfss&t=884s
https://www.youtube.com/watch?v=Mh3LaHmA21I
NHN (OAuth: 과거, 현재 그리고 미래)
'TIL' 카테고리의 다른 글
애플 소셜 로그인 (with. Spring) (1) | 2024.11.05 |
---|---|
Sysbench 벤치마크 & 테스트 데이터 (for. Mac) (0) | 2024.07.27 |
템플릿 메소드 패턴 vs. 전략 패턴 (0) | 2024.07.14 |