OAuth 인증 되새김

Buddy·2023년 9월 3일
0

최근 일이나 외부 프로젝트나 OAuth 인증 방식을 적용하고 사용함에 있어서 잘 몰랐던, 헷갈리던 부분들이 다음엔 헷갈리지 않도록.. 되새김 하고자 주제로 쓴다.

OAuth

OAuth("Open Authorization")는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다.이 매커니즘은 여러 기업들에 의해 사용되는데, 이를테면 아마존, 구글, 페이스북, 마이크로소프트, 트위터가 있으며 사용자들이 타사 애플리케이션이나 웹사이트의 계정에 관한 정보를 공유할 수 있게 허용한다.

Wikipedia 의 OAuth 설명이다. 사용자 인증에 대한 관리를 다른 서비스에 의존하는 방법이다.

장점

  • 서버에서 개인정보 관리에 대한 리스크를 줄일 수 있다.
  • 사용자에게 단순한 로그인 사용성을 제공할 수 있다.
  • 사용자의 인증 해제가 간단하다.

단점

  • 서버에서 인증 플로우가 복잡하다.

사실 크게 단점이랄게 없는 것 같다. 서버측에서는 구성하는게 좀 복잡할 수 있는데 클라이언트 개발에서나 사용자 측면에서나 간단하게 구성이 가능하기 때문에 서버 개발자가 조금 더 고생하는게 좋다고 생각한다.

표준 방식

https://oauth.net/2/

위 문서는 OAuth 인증에서 어떤 요소들을 포함해야 하는지와 필드들의 이름이나 플로우에 대해서 설명한다. 때문에 여러 서비스에서 OAuth 인증을 사용해보면 값들이나 방식이 다 비슷비슷하다.

플로우는 위처럼 Client가 인증을 요청해 권한 부여를 받고 인증 서버에 받은 권한으로 토큰을 받는다. 이 토큰으로 리소스에 접근할 수 있게 된다. Abstract 라고 써있는 만큼 가장 기본적인 추상 개념이다. 서버의 구성이나 OAuth를 제공하는 서비스에 따라서 조금씩은 다르게 적용이 될 수도 있겠다.

Access Token의 응답 형태는 위와 같다. 플로우랑 마찬가지로 구성이 조금씩은 다를 수 있겠지만 access_token, expires_in, refresh_token 과 같은 값들은 항상 비슷하다. 또 언더바(_)를 이용한 컨벤션(?)이 존재하는 것도 볼 수 있다. 지금까지 별 생각 없이(자바를 해서 더 그런 것 같다.) API를 만들 때도 반환하는 필드들을 camelCase 로 작성했는데, OAuth 인증 기능을 표준을 따라 적용해서 서비스하고 있다면 컨벤션을 이쪽과 맞게 통일하는 것도 맞을 수 있겠다.

(서비스마다 달라서 어느게 정답이라고 말을 하기는 어려울 것 같다. 추후 관련 자료를 찾아 볼 필요가 있겠음)

네이버

네이버 로그인 API 명세

인증 과정은 위에서 본 플로우와 유사하다. 설정 과정이나 request/response의 형태는 문서에 잘 설명 되어있으니 건너뛰고,
1. 인증 요청 API를 사용해 네이버 로그인 화면 띄우기
2. 네이버 로그인 인증을 성공하여 code 값을 응답 받기
3. 응답 받은 code 값으로 토큰 발급 API 요청하기
4. 발급 받은 토큰으로 네이버 API 휘뚜루 마뚜루

카카오

카카오 로그인 > REST API

카카오는 친절하게도 문서에 플로우를 그려줬다. 그래서 플로우도 생략해도 될 것 같다. 전체적인 흐름은 위에서 봤던 표준 플로우, 네이버 플로우랑 비슷하다. 과정을 step 단위로 잘라서 설명하고 있기 때문에 좀 더 이해하기가 쉽다고 느낄 수 있겠다.

GitHub

GitHub Docs

GitHub 공식 문서에서는 짧게 아래의 3단계로 플로우를 설명한다.

  1. 유저가 GitHub ID를 요청하도록 리다이렉션
  2. 사용자는 GitHub에 의해 서비스 앱으로 다시 리다이렉션
  3. 앱이 사용자의 액세스 토큰을 사용해 GitHub API에 액세스

특이한 점은 딱히 없다.


위의 세 방법 모두 사용자 인증 -> 코드 발급 -> 토큰 발급 -> API 사용 (resource 접근) 의 플로우를 가진다고 보면 될 것 같다. 카카오의 플로우에 작성된 것 처럼 처음 접근할 때 서비스가 사용자의 어떤 정보들 까지 가져갈 수 있을지 체크하는 부분들로 이메일이나 이름, 나이, 프로필 사진 등의 정보들을 수집하기도 한다.

내가 적용한 방법

그래서 이걸 어따 써먹냐?

토큰 발급까지 성공했고 해당 OAuth 서비스에서 사용자의 정보를 성공적으로 가져올 수 있다면 해당 사용자의 프로필 정보, 고유 ID값 또한 가져올 수 있다. 이 정보들을 가져오면, 사용자의 유효성이 검증됐다고 할 수 있겠다.

{
  "user": {
    "sns_type": "KAKAO",
    "name": "JTH",
    "sns_id": "1234567890"
  }
}

위와 같은 방식으로 유저를 저장한다면, sns_type, sns_id 로 유저를 식별하고 고유성을 부여할 수 있다.

단! 여기서 OAuth 로 발급받은 토큰을 내 서비스에 그대로 사용하기에는 무리가 있을 수 있다.
여러 서비스를 통해서 OAuth 인증을 지원하고 있다면, 해당 토큰들의 형태가 전부 다를 수 있기 때문이다.
또 해당 토큰의 유효성을 검증할 때 외부 API를 계속 요청해야 하는 단점도 가지고 있을 수 있다.
따라서, 토큰을 발급 받고 사용자를 조회 해 어떤 유저인지 식별이 됐다면, 사용자가 검증됐다는 것이 확인이 되었으니 내 서비스에서 해당 사용자에 대한 토큰을 발급해서 사용한다.

토큰 자체에 대한 얘기는 언젠가 토큰 관해서 글을 쓰면 그때 봅시다.

그럼 끝!

profile
가볍게 쓰는 내용들이라 주관과 틀린 내용이 많습니다. 비판적인 시각으로 봐주시고 지적은 환영 :)

0개의 댓글