OAuth를 쓰는 이유
OAuth란?
🧑🏻 : Resource Owner(서비스를 사용할 사용자)
🏢 : Resource Server(데이터를 가지고 있는 서버. Google, Naver, Kakao ...)
💻 : Client(앱,웹)
🧑🏻 ➡️ 💻 :
너가 제공하는 서비스를 사용하고 싶은데 그러기 위해선 로그인을 해야되네
근데 내 아이디, 비밀번호 등록해서 회원가입을 하기는 싫은데..
💻 ➡️ 🧑🏻 :
다른 소셜App에 회원가입이 돼있으면 그 아이디로 우리 App에 로그인 할 수 있게 해줄게
🧑🏻 ➡️ 💻 :
내 아이디와 비번을 여러 서비스에서 돌려쓴다고?
🧑🏻 : 싫어!
💻 : 아니!
🏢 : 안돼!
해서 나온게 OAuth
이다.
🧑🏻--🏢--💻 이 사이에서 안전하게 상호작용 할 수 있게 해주는게 바로 OAuth
어떻게??
참여
OAuth에는 네 종류의 주체가 참여
🧑🏻 Resource Owner (사용자: 내 서비스의 유저)
🏢 Authorization Server (인증 서버: 카카오 인증 서버)
🏢 Resource Server (자원 서버: 카카오 API 서버)
💻 Client (클라이언트: 내 서비스)
등록
내 서비스에서 SNS에 미리 등록해놓는 과정 ( 나 니네꺼좀 쓸게~~)
등록시 공통적으로 필요한 정보
- Client ID
- Client Secret
- Authorized Redirect URIs : Client가 설정
Authorization 서버가 권한을 부여하는 과정에서 Client한테 Authorized CODE를 전달해 줄 주소 + redirect 주소가 아닌데서 요청을 해버리면 무시함
인증 과정
- 사용자가 SNS에 접속
- SNS는 사용자가 로그인이 되어있는지/안되어있는지 확인해서 로그인
- 로그인이 되면 SNS는 내 서비스에있는 client id값이 유효한지 확인(SNS가 가지고 있는 id와 내가 갖고 있는 id가 같은지 확인)
- 확인된 Client_id의 redirect_uri 값이 유효한지 확인해서 다르면 차단, 같으면 사용자에게 내 서비스에 권한 넘겨준다는걸 사용자에게 확인받음.
결론: Resource Server를 통해서 Resource Owner(사용자)의 허락을 받고 인가 코드(Authorization CODE)를 발급
- Resource Server가 사용자에게 Authorization CODE를 포함한 Redirection주소(내 서비스의 주소)로 이동하라고 명령.
- 사용자는 저 주소로 이동하는지도 모르게 인가 코드를 가지고 내 서비스 사이트로 redirect
- 그럼이제 나는 Authorization CODE를 알 수 있네
- Client는 CODE + Client_id + Client_Secret을 가지고 Resource Server에 토큰(Access Token)을 요청할거야
- 리소스 서버는 위의 세 정보가 유효한지 확인하고 Client에 토큰 발급해줌
- Client는 이 토큰을가지고 API 요청.
Header에 Bearer로 토큰을 넣어서 API를 요청
curl -H Authorization: Bearer <access_token> 이런식으로
Access Token도 유효기간이 있어서 기간이 지나면 Refresh Token으로 재발급받을 수 있음
쫌 더 자세히 설명하자면
OAuth 2.0은 네가지의 권환 획득 방식을 정의하고 있어
- 권한부여코드 승인 타입 (Authorization Code Grant Type)
- 암시적 승인 타입 (Implicit Grant Type)
- 리소스 소유자 암호 자격 증명 타입 (Resource Owner Password Credentials Grant Type)
- 클라이언트 자격 증명 타입 (Client Credentials Grant Type)
이 네가지 중 권한부여코드 승인 타입
이 가장 많이 쓰이는 방법이고
저번에한 Django로 카카오 소셜로그인 구현할 때 사용한 방법이므로 1번 방법에 대해 알아보자
권한부여코드 승인 타입 (Authorization Code Grant Type)
- Client가 사용자 대신 특정 리소스에 접근을 요청할 때 사용해
- 사용자가 인증 서버에 로그인해서 건네받은 권한 코드를 Client에 넘겨주고
- Client는 권한 코드를 받아 리소스 서버에서 엑세스 토큰과 리프레시 토큰으로 교환하여 사용할 수 있어
- Client는 인증서버에 미리 등록된 Client_id와, 유저가 인가코드를 가져다 줄 리디렉션 주소를 유저에게 제공하며 유저를 인증 서버의 엔드포인트로 리디렉션시킨다.
- 유저는 인증 서버 엔드포인트에 도착해 자신을 인증하며 Client로부터 전해받은 클라이언트 신원증명과 리디렉션 주소를 인증서버에 전달한다.
- 인증서버는 유저를 인증한다.
- 만약 유저가 성공적으로 인증되었다면 인증 서버는 2에서 전해받은 리디렉션 주소로 유저를 리디렉트하며 인가코드를 전해준다.
- 유저는 Client의 리디렉션 주소로 도착해 Client에게 인가코드를 전달한다.
- 인가코드를 전해받은 Client는 인증서버로 인가코드와 1에서 유저에게 주었던 리디렉션 주소를 전해준다.
- 인증서버는 Client가 가져온 리디렉션 주소가 4에서 유저를 리디렉션 했던 주소가 맞는지 보고 가져온 인가코드를 검증한 후 유효하다면 Client에게 유저의 리소스에 대한 엑세스 토큰과 리프레시 토큰을 전달한다.
- Client는 엑세스 토큰을 가지고 리소스 서버의 API를 호출한다.
🏢 ➡️ 💻 : AccessToken
을 줄테니까 뭐 필요한거 있으면 AccessToken
들고와
🏢의 아이디, 비번을 제공하는게 아니고, 💻에 꼭 필요한 기능만 부분적으로 접근허용할 수 있게 해주는 일종의 key
정리해보자면
🧑🏻 사용자 : User : Resource Owner - 자원의 주인
💻 내서비스 : Mine(my service) : Client - 리소스 서버에 접근해서 자원을 가져오는 애
🏢 사용자가 회원가입한 SNS : Their(Google, Facebook, Twitter) :Resource Server - 자원을 갖고 있는 서버 / Authorization Server - 인증관련 처리하는 서버
🧑🏻가 💻에서 소셜 로그인(Google 등)을 통해 내 서비스의 기능을 사용하고 싶어.
이때 💻에서 🧑🏻의 google 아이디와 비밀번호를 알아서 그 아이디/비번을 이용하여 구글에 로그인한다면 🧑🏻는 개인정보 노출돼서 싫고, 💻 는 민감한 정보 관리해야돼서 싫고, 🏢은 User의 정보를 노출시켜줘서 싫어.
이 불편함을 해결해주는게 OAuth. 어떻게?
🏢 에서 Access Token을 발급해서 💻 한테 주면 아이디와 비밀번호 없이 토큰을 가지고 🧑🏻 정보를 이용할 수 있어.