RFC 6749를 공부하면서 배운 내용을 바탕으로 OAuth 구현 개발자의 입장이 아닌, 클라이언트 개발자 입장으로 OAuth 2.0
을 간략히 정리하고자 한다.
(상세 구현보다는 큰 흐름을 파악하기 쉽도록 작성하였습니다.)
네이버 로그인, 카카오 로그인를 왜 사용할까? 여러 가지 이유가 있을 수 있다. 예를 들어 쉬운 회원가입&로그인을 위해 사용할 수 있다. 회사에서 이런 이유 때문에 사용하기로 결정났다고 하자. 그러면 우리 개발자들은 이를 구현해야만 한다.
이제 기술적인 문제를 생각해보자. 우리 서비스를 사용하려는 고객이 네이버 회원임을 어떻게 알 수 있을까?
간단한 방법은 고객한테 네이버 아이디/비밀번호를 받아서 네이버에 로그인을 해보면 된다. 근데 이 방법은 말도 안되는 방법이다. 그래서 OAuth
가 생겼다.
OAuth
는 쉽게 말해서 다른 서비스의 회원 정보를 안전하게 사용하기 위한 방법이라고 생각하면 된다. 여기에서 안전하게의 주체는, 회원 정보를 가지고 있는 주체, 우리의 고객이다. 즉, 우리의 고객이 안전하게 다른 서비스의 정보를 우리 서비스에 건네주기 위한 방법이다.
고객이 자신의 네이버 아이디/비밀번호를 우리 서비스에 알려주지 않아도, 네이버에 있는 고객의 정보를 우리 서비스에서 안전하게 사용하기 위한 방법이다.
OAuth
의 핵심은 Access Token
이다. 이 Access Token
은 임의의 문자열 값인데, 이 문자열의 정체는 이 토큰을 발급해준 서비스만 알 수 있다. 물론 JWT의 경우 기본정보가 Base64
인코딩으로 되어 있어서 정보를 살펴볼 수 있긴 하지만, 어쨌든 기본적으로 Access Token
은 토큰을 발급해준 서비스가 알고 있다고 생각하면 된다.
이 Access Token
을 이용해, 이 토큰값과 관련된 고객의 정보를 우리는 해당 서비스에 요청할 수 있다. 해당 서비스는 이 토큰을 검증하고, 발급된게 맞다면 해당 고객의 정보를 넘겨준다.
즉 Access Token
의 존재 자체가 고객이 정보를 넘겨주는 것을 동의함의 징표라고 할 수 있다.
Access Token
을 넘겨주면 네이버는 정보를 넘겨준다. 참 쉽다. 이걸 위해서 우린 OAuth
를 사용한다.
그럼 우리는 Access Token
을 어떻게 네이버로부터 받을 수 있을까? 당연하지만 네이버가 건네줘야 된다.
네이버는 어떻게 특정 고객의 Access Token
을 발급해줄까? 특정 고객이 네이버 회원임을 인증해야 한다. 그러면 어떻게 인증하면 될까? 그 고객이 네이버에 로그인을 하면 된다.
네이버 로그인, 카카오 로그인 버튼을 클릭하면 네이버 로그인 페이지로 이동하고, 카카오 로그인 페이지로 이동한다. 그 고객임을 인증하기 위해서다.
Access Token
넘겨 받기고객이 네이버에 로그인을 했다. 네이버 서버에서는 아이디/비밀번호를 확인하고 해당 고객이 네이버 회원임을 확인했다. 그러면 이제 이 고객과 관련된 Access Token
을 발급한다.
이 토큰을 우리 서비스에서 어떻게 받을 수 있을까? 여러가지 방법이 있을 것이다.
가장 단순한 방법은, 보통 회원 가입할 때 핸드폰 인증을 받는 형식의 방법이 있을 수 있다. 네이버에 로그인을 하면, 네이버가 토큰값을 화면에 출력한 뒤 고객이 이 토큰을 복사해서, 우리 서비스의 토큰을 입력하는 페이지에 접속한 뒤 토큰을 붙여넣기 하면 될 것이다.
그런데, 이건 너무 귀찮다. 매번 로그인 할 때마다 이렇게 복사/이동/붙여넣기 할바에는 그냥 안하는게 낫다. 아마 고객은 이 기능을 사용하지 않을 것이다.
음, 또 다른 방법이 뭐가 있을까?
HTTP에는 리다이렉트 메시지가 존재한다. 이 메시지는 참으로 간단하다. 서버에서 클라이언트보고 어디로 가라고 지정해주는게 바로 리다이렉트다.
리다이렉트를 이용하면, 고객이 가만히 있어도 웹브라우저가 알아서 페이지를 이동한다. 이를 이용하면 고객이 직접 페이지를 이동할 필요가 없어진다.
고객이 로그인을 하고, 네이버에서 다시 우리 서비스로 리다이렉트 시켜주면 고객은 가만히 앉아서 우리 서비스로 넘어올 수 있다. 귀찮음은 해결했다! 그럼, 토큰값은 어떻게 받아올까? 간단하다. URL에 묶어서 건네주면 된다. 우리에겐 query string이 있으니 말이다.
그럼, 이 리다이렉트 되는 URL은 어디일까? 네이버는 어디로 이 고객을 보내주면 될까? 리다이렉트 URL을 우리가 네이버에 알려줘야 될 것 같다. 그래야 URL에서 토큰값을 추출하는 로직을 해당 페이지에서 처리할 수 있게 구현할 수 있을테니 말이다.
어떻게 알려줄까? 네이버가 우리 서비스에 토큰값을 어떻게 보내주더라? URL에 묶어서 보내줬구나. 그럼 우리도 URL에 리다이렉트 URL을 묶어서 네이버로 이동시키게 하면 되겠네!
이런 이유로, 네이버 로그인을 클릭하고 이동된 URL을 유심히 살펴보면, redirect_uri
값이 있음을 알 수 있다.
잠깐! 그런데, 이러면 문제가 하나 있다. 어떤 악의적인 사용자가 XSS공격이나 피싱 사이트를 이용해서 redirect_uri
를 자기가 원하는 사이트로 바꾸면 어떡하지? 그러면 그 공격자는 내 Access Token
을 받을테고, 정보를 쉽게 알 수 있잖아?🤔
이런 위험을 막기 위해, 각 사이트는 OAuth
를 사용하려면 우선 해당 서비스에 등록절차를 밟아야 한다.
즉, 우리 서비스에서 네이버 로그인 기능을 사용하려고 한다면 사전에 네이버에 등록을 하고 승인을 받아야 한다.
그리고 이런 등록 과정에서, 여러가지 정보를 기입하는데 이 때 redirect_uri
도 사전에 미리 합의를 본다. 이미 합의된 redirect_uri
가 아닌 다른 값으로 로그인 요청 페이지로 보냈다면, 네이버에서는 이를 수상한 행동으로 여기고 보내주지 않을 것이다.
우여곡절 끝에 Access Token
을 우리 서비스에서 받았다. 그러면, 이제 이 토큰을 가지고 어떻게 회원의 정보를 얻을 수 있을까?
아마 네이버에 Access Token
을 건네주면, 이 토큰을 확인하고 네이버가 정보를 건네주는 페이지가 있을 것이다.
이렇게 말이다. 그 다음은 너무 쉽다. 네이버에서 하라는대로 Access Token
을 넘겨주면, 네이버는 정보를 전달해준다. 끝!
OAuth
는 위에서 살펴봤듯, 크게 3단계로 나뉘어져 있다.
나머지는 상세 구현이다. 어떻게 안전하고 편리하게 위의 과정을 진행할 것인지에 대한 고민의 결과가 바로 구현에 나타나 있는 것이다.
이를 파악하면, 네이버 뿐만 아니라 다른 서비스들도 쉽게 사용할 수 있다. OAuth 2.0
은 표준이 존재하기 때문에, 대부분의 서비스에서는 이 표준에 맞게 구현했을 것이기 때문이다.
쉽게 설명해 주신 덕분에 많은도움 받았습니다! 감사합니다 :)