본문 바로가기
SW 개발/REST API

Google Gmail API 사용 방법 (2) - Sample code

by Kibua20 2020. 7. 5.

앞선 게시글에서 Google API 콘솔에서 프로젝트를 생성한 후 credential.json을 얻는 방법을 설명하였고, 본 게시글은 아래 그림에서는 붉은색으로 표시한 '구글 인증 서버에 Authoized code를 요청 후 Access toekn을 받는 방법'을 설명하고자 한다.

 

[모바일/REST API] - Google Gmail API 사용 방법 (1)

[모바일/REST API] - Google gmail API 사용 방법 (3)

 

 

Google API 호출을 위한 전체 Flow (Web Server Application flow로 진행)

 

 


Step 2. 구글 인증 서버에서 Authorization code 받기

구글에 OAutho 2.0 의 Web server application에서 설명된 https request 방법을 먼저 확인해야 한다.  구글의 샘플 코드를 보면 아래와 같다.  https://accounts.google.com/o/oauth2/v2/auth로 접속하고, URL의 파라미터는 scope, access_type, includ granted scope, response_type, state, redirect_url, client_id를 전달한다. 이 중 API 별로 변경해야 하는 값은 scope, redirect_url, client_id 값이고 상세 설명은  API reference를 확인해야 한다.

<구글 Authorization code 받기 위한 샘플 코드>

https://accounts.google.com/o/oauth2/v2/auth?
    scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
    access_type=offline&
    include_granted_scopes=true&
    response_type=code&
    state=state_parameter_passthrough_value&
    redirect_uri=https%3A//oauth2.example.com/code&
    client_id=client_id

 

scope: 사용하고자 하는 API를 인증 범위를 의미하며 사용자 로그인 시 scope 에 대해서 명시적 동의를 받는다. 만일 soce에 여러개라면 각각 space로 구분해서 추가할 수 있다.   예를 들어  Gmail의 Users.message:send API는 아래와 같이 명시되어 있다.  .

Gmail send message의 scope
scope 파라미터 설명

 

  • access_type: online 과 offline으로 설정할 수 있으며 'offline'으로 설정한다. access token은 한 번 받으면 1시간 동안만 유효하고, 유효한 시간에서만 API 호출이 가능하다. access_token을 다시 받기 위해서는 refersh token을 받아야 하고  사용자 로그인 없이 refresh token을 사용해서 access token을 받을 수 있다.  사용자로 하여금 API 사용할 때마다 로그인을 할 수 없기 때문에 refersh token을 얻은 것은 서비스 개발자의 입자에서는 매우 중요하다.  (아래 설명 참고)

access_type설명

  • redirect_uri:  사용자 권한 동의를 구글 인증 서버로 요청하고 Authoization code와 access token을 받을 수 있는 URL을  설정한다. Google API Console에서 추가한 값으로 credential.json 파일에 있는 값을 사용해야 하고, 일치하지 않는 경우 에러가 발생한다. 

  • client_id:  Google API console에서 만든 OAutho client를  의미하고 crendential.json 파일의 client ID 값과 일치해야 한다.

 

2.1.Authorization code  받기 

구글의 https://accounts.google.com/o/oauth2/v2/auth 에 URL paramter를 전달하는 단계이다.  아래와 같이 URL 파라미터로 API에 맞게 변경하고 URL을 공백 없이 한 줄로 만들어서 Chrome 브라우저에 URL 값에 입력한다.  Chome 브라이저에서 URL 위에 parameter 값을 URL encoding 변환하기 때문에 별도의 URL ending은 필요 없고 공백만 없이 입력 정상 동작한다.  만일 html이나 java script에서 URL을 입력하는 경우 paramter 부분을 URL encode를 수행해야 한다.

 

Google 인증 서버에 Authorization code 요청

 

Authorization URL을 입력이 되면 아래와 같이 구글 계정 로그인 화면을 표시하고,  계정 사용자에 대한 패스워드 인증 및 API scope에 대한 명시적 동의를 얻는다.

 

1) Authorization URL을 전달하면 구글 계정 서버에서 계정을 선택 화면을 표시한다.

2) 확인되지 않은 앱: Google API console에서 권한을 신청할 때 구글의 Verification Process 리뷰를  받아야 한다. 현재는 Test 용이나 서버용 계정이기 때문에 구글 리뷰를 받을 필요는 없고, 고급 메뉴에서 App 동의 화면을 선택한다.

3) 고급> App 화면으로 이동 선택

4) 사용자에게 API의 scope에 대한 명시적 동의를 받는다. 설정된 scope에 대한 확인 과정을 진행한다.

5) API에 개인정보 접근에 대한  최종 확인 

 

Google 인증 서버에 Authorization code 요청: 사용자의 명시적인  동의를 받는다 

 

Google 인증 서버에 Authorization code 요청: 사용자의 명시적인  동의를 받는다 

 

 

Step 3. Authoization code값을 활용해서  Access token을 받기

 

사용자가 API의 scope을 명시적으로 동의하고 구글 서버에 제출하면 redirect URL로 인증 결과(authorization code)를 전달한다.  아래 그림에서는 Chrome 브라우저에서 URL의 위치가 구글 서버에서 localhost를 변경됨을 확인할 수 있다. 그 세부 내용을 보면 Redirect URL에 state, code, scope이 전달되어 있음을 알 수 있다. 

 

6) 구글 인증 서버에서 Redirect URL로 authorization code를 전달 받음

7) 구글 서버에서 code 값, client ID, client_secret, redirect URL, grant type을 설정하여 구글 서버에 https 의 request 전송

8) 구글 서버에서는 reponse에 refresh token과 access token을 reponse 한다. 

 

Repsonse 를 보면 access_token, expires_in, scope이 명시되어 있다. 이 중에 expireds_in 값는 access token의 유효한 시간 값으로 3600초(= 1시간)의 유효 시간을 가지고 있다.

 

Authoization code를 활용해서 access token 받기

7) 번 과정은  http의 post와 동일한 값을 가진다.  Html의 java script을 구성이 가능하면, curl이나 python으로도 request를 호출해도 access token을 얻을 수 있다.  

Access token을 획득하기 위해서 http request

 

 

 

참고) Redirect URL을 위한 receivecode.html  (출처: 생활 코딩)

receivecode.html 은 구글 인증 서버에서 내려주는 URL 중 code 값을 찾아서 다시 post 하는 코드이다.

<!DOCTYPE html>
<html>
<body>
<style>
  input{  width:300px; }
</style>
        
<form action="https://www.googleapis.com/oauth2/v4/token" method="post" enctype="application/x-www-form-urlencoded">
code : 
<input type="text" id="codebox" name="code"><br>
client_id : <input type="text" name="client_id" value="178730211101-6f69st2m3ajb3je2clsdm15e3cv7170e.apps.googleusercontent.com"><br>
client_secret : <input type="text" name="client_secret" value="RIQqjr77Nfrt9gSGnihfQRPe"><br>
redirect_uri : <input type="text" name="redirect_uri" value="http://localhost:8080/receivecode.html"><br>
grant_type : <input type="text" name="grant_type" value="authorization_code"><br>
<input type="submit">
</form>

<script>
        function getHttpParam(name) {
            var regexS = "[\\?&]" + name + "=([^&#]*)";
            var regex = new RegExp(regexS);
            var results = regex.exec(window.location.href);
            if (results == null) {
                return 2;
            } else {
                return results[1];
            }
        }
        var ret = getHttpParam("code");
        document.getElementById("codebox").value = ret;
</script>

</body>
</html>

 

Check Point #1.

Web server의 정상 동작 여부를 확인해야 합니다.  http://localhost:8080 or http://localhost 가 정상적으로 표시되어야 한다. 만일 정상적으로 표시되지 않는다면 apache2와 tomcat9 버전으로 설치해야 한다. (설치 방법)

 

Check point #2. 

Web server가 정상 동작하는 상태에서 Google 계정이 표시 안되고, URL에러가 발생하는 경우는 URL 에 붙는 paramter를 URL 인코딩을 해야 한다.  즉 URL parameter는 space 나 '/' 를 사용할 수 없기 때문에 URL encoder으로 변환해야 한다.

 

 

관련 글:

[모바일/REST API] - Google Gmail API 사용 방법 (1)

[모바일/REST API] - Google gmail API 사용 방법 (3)

 

[모바일/Python] - Python 표준 입출력(stdin/stdout) 활용 - 리눅스 프로그램과 연동

[모바일/Python] - Python JSON 사용 시 TypeError: Object of type bytes is not JSON serializable

[모바일/Python] - Python smtplib 사용한 email 발송 예제 (gmail)

[개발환경] - [Memo] 우분투에서 gmail 활용하여 command line으로 email 전송

[모바일/REST API] - 우분투 20.04에서 Web 서버 설치 방법 (apache2, tomcat9)

 




댓글21