Authentication으로 사용자의 신원을 확인하는 것을 인증이라고 합니다.
예를들어 경찰이 시민에게 이름과 주민등록번호를 요청해서 신원을 확인하는 절차를 인증 이라고 합니다.
Authorization으로 사용자의 권한을 확인하고, 허가하는 절차입니다.
단 인가는 무조건 인증절차를 거친 후에 진행됩니다.
예를 들어 술을 마신 A씨가 대리운전을 불러 자동차 키를 대리운전 기사님께 주며 A씨의 자동차의 사용 권한을 대리운전 기사님께 위임하게 되는데 이것을 인가라고 합니다.
예를 들어 스터디원들의 일정을 통합해서 관리하는 치맨 캘린더 서비스가 있다고 가정해 보겠습니다.
치맨 캘린더는 구글 캘린더에 일정을 추가하거나, 일정을 볼 수 있어야 합니다.
이때 Oauth를 사용하지 않는다면?
1. 스터디원들은 치맨 캘린더에 구글 ID, Password를 입력합니다.
2. 스터디원으로부터 입력받은 구글 ID, Password를 통해 치맨 캘린더에서 구글에 로그인합니다.
결과적으로 모두에게 좋지 않은 결과를 발생시킬 수 있는 상황이 발생합니다.
사실 치맨 캘린더 입장에서는 사용자의 권한이 필요한 거지 사용자의 ID, Password를 굳이 가질 필요는 없습니다.(다만 권한을 갖기 위해선 인증이 필요하기 때문에 Id,Password가 필요했던 거죠)
이때 사용자의 인증은 직접적으로 구글에서 받고, 치맨 캘린더에선 권한만 받을 수 있도록 사용되는 프로토콜이 Oauth입니다.
출처 : 위키백과에는 아래와 같이 설명되어 있습니다.
사용자의 권한을 받아 어떤것을 활용하는 즉 사용자가 방문한 웹사이트
위의 예시에선 치맨캘린더를 의미합니다.
Resource Owner를 확인해서 신분을 인증
하고 Oauth Client에게 역할을 인가
하는 역할을 합니다.
위의 예시에선 구글을 의미합니다.
공식 메뉴얼에서는 Resource Server를 2개로 나눌 수 있습니다.
Authorization Server
도 존재 하는데 이곳은 인증과 관련된 서버를 전담하는 서버이고 Resource Server
는 Data를 가지고 있는 서버를 의미합니다. 하지만 2개의 서버를 합쳐서 Resource Server로 정의해서 예를 들어 보겠습니다.
Oauth Client는 Resource Server의 기능을 사용하기 위해 미리 등록을 해둬야 합니다.
주로 Resource Server의 개발자 홈페이지에서 등록을 하며, 각자 약간의 차이가 있지만 주로 HompageURL, Authorized redirect URL을 등록합니다.
등록절차를 통해 3가지를 부여받습니다.(사이트별로 약간의 차이는 있을 수 있습니다)
사용자가 인증을 마치면 클라이언트를 명시된 주소로 리다이렉트 시키는데, 이 때 Query String으로 특별한 Authorization Code가 함께 전달됩니다.
클라이언트는 해당 Authorization Code와 Client ID 및 Client Secret을 Resource Server에 보내, Resource Server의 자원을 사용할 수 있는 Access Token을 발급 받습니다.
카카오 개발자 홈페이지로 접속합니다. 카카오 개발자 사이트
왼쪽 상단의 내 애플리케이션
을 클릭후 애플리케이션 추가하기를 클릭합니다.
여러가지의 키들을 발급받을 수 있습니다.
플랫폼 창으로 이동하면 리다이렉트 URL을 등록할 수 있습니다.
Resource Owner는 Resource Server에 인증을 해야합니다.
승인 절차는 아래와 같이 진행됩니다.
카카오로 로그인하기
버튼을 누릅니다.카카오 로그인을 REST API로 요청하기 위해 저는 카카오 개발자 사이트에서 REST API를 클릭합니다.
그러면 인가코드를 받기 위한 기본적인 URL주소가 나타납니다. 추가적으로 쿼리 파라미터를 작성해줘야 하는데 사이트별로 다르지만, 카카오에선 client_id, redirect_uri, response_type(code로 고정) 3개는 필수적이고, 나머지는 옵션으로 지정해줘야 합니다.
그러면 기본적으로 요청할 주소는 아래와 같이 작성할 수 있습니다.
추가적으로 scope 등 옵션으로 기본적인 URL코드의 맨 뒤에 &scope=원하는항목 을 사용해서 추가할 수 있습니다.
사용자가 카카오로 로그인하기 버튼을 클릭하면 위에서 만들어둔 코드로 이동하게 만들어줍니다.
이곳으로 이동하면 사용자는 ID, Password를 입력하고, 원하는 기능에 대해 권한을 체크한 뒤 확인 버튼을 누를 수 있는 화면으로 넘어가게 됩니다. 이때 원하는 기능에 대한 권한은 scope를 통해 추가해줄 수 있습니다.
최종적으로 Resource Owner가 Resource Server에게 Client의 접근을 승인하게 됩니다.
인증이 완료되면 Resource Server는 Authorization Code를 URL에 추가하여 리다이렉트 URL로 이동시킵니다.
Oauth Client측은 Authorization Code를 얻게 되고, client_id, client_secret을 통해 Resource Server에게 승인을 요청합니다.
Resource Server는 Oauth Client측에서 보낸 모든 정보가 Resource Server가 가지고 있는 정보와 동일하면 Oauth Client측으로 Access Token을 전달해줍니다.
Oauth Client측에서 Access Token을 받아 서버에 저장해두고, Resource Server의 기능을 사용하기 위한 API 호출시 해당 토큰을 헤더에 담아 보냅니다.
Oauth Client측에서 특정 기능을 사용할 때 발급받은 Access Token을 헤더에 담아서 API 요청을 할 때 같이 전송하여 Resource Server로부터 정보(Data)들을 가져와 가공해서 사용하면 됩니다.
구글 API로 예로 들었을 때 아래의 사진과 같이 2가지 방식으로 요청이 가능합니다.
1. Access-Token을 query parameter로 보낸다.
2. API 요청시 헤더에 Access-Token을 보낸다. (이 방법을 더 선호)
Access-Token은 만료 시간이 있습니다.(비교적 짧게 구성)
그러면 Access-Token의 기간이 만료되면 위의 절차를 다시 진행하는건 사용자 경험 측면에서 좋지는 않습니다. 만약 Access-Token의 기간이 짧으면 인증 절차를 자주 진행해야겠죠. (단 보안이 중요된다면 일부로 다시 로그인 하도록 하는 경우도 있습니다)
처음 인증 절차에서 Refresh Token은 Access-Token과 같이 발급 받으며, Refresh Token은 Access-Token 보다 더 긴 만료기간을 가지고 있으며, Access-Token이 만료되면 Refresh Token을 통해 Access-Token을 다시 발급 받아 사용자의 인증을 유지할 수 있습니다.
좋은 글이네요. 공유해주셔서 감사합니다.