: OAuth 2.0(Open Authorization 2.0) 인증은 페이스북, 구글, 네이버 등에서 사용할 수 있는 사용자 인증 방식이다. 대표적인 OAuth 2.0의 예가 특정 서비스를 로그인할 때 회원 가입을 하지 않고 페이스북이나 네이버 아이디로 로그인을 하는 것이다.

 

※ OAuth 2.0 주체

- Client : 개발자가 만들고 서비스하고 있는 웹/앱

- Resource Owner : Client를 사용하는 서비스 사용자

- Resource Server : Owner의 리소스(데이터)를 가지는 페이스북, 구글, 트위터, 네이버 등의 서버

=> Owner가 Resource Server에 저장한 데이터를 Client에서 사용하고자 할 때 OAuth 2.0 방식을 이용한다.

 

※ OAuth 2.0 구현 절차

: 사용자의 구글 캘린더 정보를 앱에 불러오는 절차를 볼 것이다.

 

1. 클라이언트를 구글(Resource Server) API 콘솔에서 OAuth 인증에 등록한다. 등록하면 구글에서 Client ID와 Client secret 값을 발급해준다. 클라이언트는 2개의 값을 저장하고 특히, Client secret 값은 외부에 절대 노출되서는 안 된다.

 

2. 사용자(Resource Owner)가 Client의 구글 캘린더 정보가 필요한 페이지에 접속한다.

 

3. Client는 사용자에게 구글 캘린더 정보가 필요하다는 문구를 담는 인증 요청 페이지를 보여준다.

 

4. 사용자가 인증 요청에 대해 승인하면 Client는 Resource Server(구글)에 접속하고 구글은 사용자에게 로그인 화면을 보여준다. 구글 로그인 화면은 Client가 별도로 개발하지 않아도 된다.

 

5. 사용자가 로그인에 성공했다면 Client가 요구하는 Scope를 보여준다. Scope는 Client가 필요로 하는 정보를 일컫는다. 여기서는 Scope는 구글 캘린더 정보이다. 따라서 사용자는 "현재 이 Client가 Resource Server 구글의 캘린더 정보를 사용하려고 합니다. 동의합니까?"와 같은 문구를 보게 된다.

 

6. 사용자가 허락하면 Resource Server는 Client에게 Code값을 전송한다. Code값은 사용자(Resouce Owner)가 Client에게 Resource Server 구글의 캘린더 정보의 제공을 승인했다는 정보를 가진다.

 

7. Client는 Code값, Client ID, Client secret 값을 Resource Server 구글에 보낸다. Resource Server 구글은 받은 정보를 토대로 사용자 Resource Owner가 정보를 제공하기로 승인한 Client가 맞는지 검증한다.

 

8. 검증 결과가 유효하다면 Resource Server는 Client에게 Access Token을 발급한다. Client는 Access Token을 DB 등에 보관하고 Access Token을 이용해서 Resource Server 구글 캘린더 정보를 요청한다.

 

9. Resource Server 구글은 Client가 보낸 Access Token을 보고 자기가 발급한 적이 있는 Token 값이면 Resource Owner의 캘린더 정보를 Client에게 보낸다.

 

OAuth 2.0의 절차에 대해서 알아보았다. 몇 몇 절차에 대한 세부적인 내용을 알아보겠다.

먼저 4번 절차에서 사용자가 인증 요청에 대해 승인을 하면 다음 형식의 URL을 전송하면 된다. 그러면 구글 로그인 화면이 자동으로 나온다.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&
 access_type=offline&
 include_granted_scopes=true&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Foauth2.example.com%2Fcallback&
 response_type=code&
 client_id=client_id

scope는 5번 절차에서 설명했다. scope에 들어가는 값은 구글 API 콘솔 사이트에 나와있다. access_type은 online과 offline이 있다. Access Token은 Client가 계속 가지고 있으면 유출도 될 수 있고 Resource Owner 사용자가 Client에게 정보 제공을 거절하고 싶을 때 문제가 발생한다. 따라서 Access Token은 수명을 가진다 보통 1시간이다. 그래서 수명이 끝나면 Access Token은 사라지기 때문에 다시 Resource Owner 사용자에게 승인 허가를 받고 Resource Server에 다시 Access Token을 받아야 한다. 이러한 절차를 반복하는 것은 비효율적이기에 만약 access_type을 offline으로 하면 Resource Server는 Access Token을 줄 때 Refresh Token도 같이 준다. Refresh Token은 Access Token이 수명을 다해 사라지면 Client가 Resource Server에게 Refresh Token을 보내 Access Token을 다시 받을 수 있다. 단, Refresh Token은 Access Token을 처음 받을 때만 받을 수 있다. redirect_url은 code 값을 Resource Server에서 보낼 때 보낼 주소값이다. client_id는 1번 절차에서 발급 받은 Client_ID를 넣으면 된다. 나머지 파라미터는 알 필요는 없다.

6번 절차의 경우 Code 값은 4번 절차에서 redirect_url 값으로 줬던 url로 파라미터 형식으로 전송된다. 예로 http://redirect_url/?code=4/코드값 형식으로 Client는 받게 된다. Client는 받은 코드값을 URL String에서 추출한 후 DB에 저장한다. 그리고 Access Token을 받아야 되기 때문에 7번 절차에서와 같이 Code값, Client ID, Client secret 값을 서버에 전송해야 한다. 형식은 다음과 같다.

POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https://oauth2.example.com/code&
grant_type=authorization_code

Post 방식으로 위와 같이 보내야 한다. grant_type을 제외하고 나머지는 알 것이라고 생각한다. grant_type은 일반적으로 authorization_code를 입력하되 Refresh Token을 이용해 Access Token을 받아야 할 시 refresh_token이라고 입력해야 한다. 추가로 code와 redirect_uri 항목을 제거하고 refresh_token=Refresh Token 값 파라미터를 넣어주면 Refresh Token으로 Access Token을 얻을 수 있다. 위 방식으로 AccessToken을 요청했을 시 Resource Server는 JSON 방식으로 다음과 같이 Access Token을 받는다.

{
  "access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in":3920,
  "token_type":"Bearer",
  "refresh_token":"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

마지막 9번 절차에서 Client에서 구글 정보를 요청할 때는 파라미터에 access_token값을 넣거나 Authorization헤더의 Bearer 값에 Access Token 값을 넣는 방식이 있다.

GET https://www.googleapis.com/drive/v2/files?access_token=<access_token>

GET /drive/v2/files HTTP/1.1 Authorization: Bearer

<access_token> Host: www.googleapis.com/

+ Recent posts