로그인 구현할 때 OAuth OAuth 하는 것 같던데 OAuth가 도대체 뭐길래?
여러 이유가 있을 수 있지만, 예를 들어 쉬운 회원가입 로그인을 위해 사용한다고 해보자.
우리 서비스를 사용하려는 고객이 네이버 회원임을 어떻게 알 수 있을까?
가장 간단한 방법은 고객에게 아이디/비밀번호를 받아서 네이버에 로그인 해보면 된다 🧨 (미쳤습네까 휴먼)
그래서 OAuth가 생겼다.
OAuth는 다른 서비스의 회원 정보를 (고갱님 입장에서)안전하게 사용하기 위한 방법이다. 즉 우리 고객이 안전하게 다른 서비스의 정보를 우리 서비스에 건네주기 위한 방법이다.
다시 말해 고객이 자신의 네이버 아이디/비번을 알려주지 않아도 네이버에 있는 고객의 정보를 우리 서비스에서 안전하게 사용하기 위한 방법이다.
OAuth는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다.
-wiki-
❕❕EX
Access Token
OAuth의 핵심.
임의의 문자열인데 이 문자열의 정체는 이 토큰을 발급한 서비스만 알 수 있다.(물론 JWT는 Base64인코딩된 형태라서 정보를 까볼 수 있다.)
이 Access Token을 이용해 이 토큰과 관련된 고객의 정보를 우리는 해당 서비스에 요청할 수 있다. 해당 서비스는 이 토큰을 검증하고 발급된게 맞다면 해당 고객의 정보를 넘겨준다.
즉 Access Token 은 존재 자체가 고객이 정보를 넘겨주는 것을 동의함의 징표이다.
Resource Owner
웹서비스를 이용하려는 유저(나)
Resource(개인정보) 소유주
Client
어플리케이션 서버
❓왜 서버 주제에 이름이 client인가?
나중에 나올 Resource server에 필요한 자원을 요청하고 필요에 따라 응답하는 포지션이기 때문이다.
Authorization Server
권한(client가 인증에 사용할 티켓. Authorization Code)을 발급해서 Resource Owner(사용자)에게 주는 서버
사용자는 이 서버로 ID, PW를 넘겨 Authorization Code를 발급받을 수 있다.
Client는 이 서버로 Authorization Code를 넘겨 Token을 받을 수 있다.
🤔 사용자는 client의 Redirect URL(네이버 로그인 api에 서비스 등록할 때 지정한 callback URL)한테 Authorization Code를 넘기는 과정이 필요하겠군..
🤔 어차피 Access Token만 받는 용도니까 일회성 토큰이어도 되겠다
Resource Server
사용자의 개인 정보를 가지고 있는 애플리케이션
google, facebook, kakao ... 회사의 서버
client는 token을 이 서버로 넘겨 개인 정보를 응답받을 수 있다.
❗️아까 Authorization server에서 받은 token을 여기서 쓰는구나!
🤔 clientID는 어디에 쓰는걸까?
사용자가 client에 직접 로그인 하는게 아닌 소셜 미디어로 로그인 할 경우,
client는 resource server에 자사 서비스 로그인에 필요한 사용자의 정보를 요청해서 받아
→ 자사가 저장한 사용자의 정보와 비교해
→ 유효한지 검증한다.
🤔 즉 client는 resource owner를 대신해 로그인한다고 볼 수 있다.
이를 위해서 client는 다음의 과정을 가진다.
1. resource owner로 부터 정보 접근 동의를 얻어야 한다.
2. resource server로 부터 client의 신원을 확인받아야 한다.
😎 resource owner
client.. 내 정보를 이용한다고? 어떤 정보 볼건데? 어떤 기능 볼건데? 내 정보 마구잡이로 악용하는건 아니겠지?
😀 Client
고갱님 저희는 고갱님의 어떤어떤 정보를 이용할거고...
🤔 Resource Server
client 너 진짜 우리한테 resource 제공받기로 한 업체 맞아? 안되겠다 우리가 고갱님한테 보낸 코드(client 식별값, 밑에서 나오는 client id) 내놔봐.
❓리소스 서버가 언제 사용자한테 client 식별자 값 보내줬대?
http://localhost:3000/url_where_you_encounter_when_you_got_authorized
Client ID
client(내 서비스)를 식별하는 식별자ID
resource server는 이 clientID를 보고 수많은 협력 업체(client들)중에 어떤 업체에게 제공할 것인지 구분한다.
Client Secret
Client ID에 대한 비밀번호로 외부 노출 NEVER
이후 사용할 42api포함 대부분의 api들이 Resource Server와 Authorization Server가 합쳐진 형태이므로 이들을 합쳐서 설명하겠다.
https://resource.server/? # 리소스 서버(네이버, 카카오 사이트 url)
client_id=1 # 어떤 client인지를 id를 통해 Resouce Owner에게 알려주는 부분
&scope=B,C # Resource Owner가 사용하려는 기능, 달리 말해 client가 자신 서비스에서 사용하려는 Resource Server 기능을 표현한 부분
&redirect_uri=https://client/callback # 개발자 홈페이지에 서비스 개발자가 입력한 응답 콜백.
4. 요청을 받은 Resource SErver는 client가 보낸 정보(client ID, redirect uri)와 스스로에게 등록된 정보를 비교한다.
확인이 완료되면 resoure Server로부터 전용 로그인 페이지로 이동해 사용자에게 보여준다.
5. ID, PW를 적어 로그인을 수행하면 Resource Server는 client가 사용하려는 기능(scope)에 대해 Resource Owner의 동의를 구한다.
사용자가 allow 버튼을 누르면 resource owner가 동의했다는 소식이 resource server에게 전달된다.
6. 하지만 사용자가 client의 권한을 승인했더라도 아직 resource server가 허락하지 않았다. 고로 resource server도 client의 권한을 허락하기 위해 Authorization code 를 redirect url의 쿼리스트링에 넣어서 사용자에게 리다이랙션 시키고 사용자는 그 주소 그대로 client에게 요청한다.
이제 client가 resource server에게 직접 url(client ID, client secret, authorization code ...)을 보낸다.
resource server는 client가 전달한 정보를 비교해 일치하면 access token 을 발급한다. 그리고 쓸모를 다 한 authorization code 는 지운다.
그렇게 토큰을 받은 client는 사용자에게 로그인이 드디어 완료 되었다고 응답한다.
이제 client는 resource server 의 api를 요청해 resource owner의 정보를 사용할 수 있다.
access token이 만료되어 401 에러가 나면 refresh token을 이용해 access token 을 재발급 받는다.
보통 resource server는 access token을 발급할 때 refresh token을 같이 만든다.
client는 두 token을 같이 저장해두고 resource server의 api를 호출할 때는 access token만 사용하다가 401 에러가 발생했을 때 보관중이던 refresh token을 보내 새로운 access token을 발급받아 로그인 인증을 유지한다.
ref
https://velog.io/@undefcat/OAuth-2.0-%EA%B0%84%EB%8B%A8%EC%A0%95%EB%A6%AC
https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-OAuth-20-%EA%B0%9C%EB%85%90-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC
https://tecoble.techcourse.co.kr/post/2021-07-10-understanding-oauth/