티스토리 뷰

 Spring Boot Application으로 만든 채팅 봇에 제 구글 계정의 Calendar를 연동하여 스케줄 일정을 봇을 통해 확인 가능하도록 구현해보았습니다. 다시 한번 정리를 하며 구글 API를 처음 연동하시는 분들께 도움이 되었으면하여 글을 작성합니다!



구글에서 프로젝트 생성 및 설정

 구글 API를 사용하기 위해서는 API 프로젝트를 생성해야 합니다. API 프로젝트는 해당 사용자에게 필요한 정보를 요청하고 사용자의 승인을 통해 사용자의 정보에 접근하기도 하며, 서비스 계정을 통해 특정 키를 통해 API에서 제공하는 기능을 제공하기도 합니다. Calendar API는 사용자의 동의를 통해 사용자 정보에 접근하는 API 입니다.


 처음은 프로젝트 생성 합니다. 구글 API 콘솔에 접속하여 프로젝트를 생성합니다. 첫 프로젝트라면 처음부터 생성하는 화면이 나올 것이고, 이미 프로젝트가 있다면 우측 상단 탭을 통해 프로젝트를 생성합니다. 기존 프로젝트를 사용해도 됩니다.


 프로젝트를 생성했다면 개요 탭에서 우리가 사용할 Calendar API를 사용 설정 합니다! 아래 설명을 보면 이 API를 통해 사요자 인증 정보 사용이라는 문구가 보입니다.

다음은 사용자 인증 정보 입니다.

 

첫 번째. 사용자 인증 정보


 필요한 사용자 인증 정보를 생성하는데 위 설명과 같이 Calendar API는 Oauth 클라이언트 ID 인증 정보를 필요로 합니다. 그래서 생성!


 


 위와 같이 사용자 인증 정보가 생성되었습니다. 앞으로 사용자는 생성한 클라이언트 ID를 통해 API 프로젝트에 접근할 것 입니다. 오른쪽 빨간 네모로 표시해논 버튼을 클릭하면 client_secret.json을 다운받을 수 있습니다. 이 json는 구글 인증 시 프로젝트 서비스 정보로 사용하게 될 정보가 담겨 있습니다! 다운로드 받아서 프로젝트의 적당한 경로에 배치합니다.


두 번째. Oauth 동의 화면


사용자가 해당 서비스에 접근하기 위해 로그인했을 때 사용자의 동의를 구하는 화면이 나오게 됩니다. 그 때 표시면 서비스 이름과 각종 정보들입니다! 제가 만들 봇의 이름은 울트론이므로 울트론으로 설정했습니다.


세 번째. 도메인



 해당 서비스로 접근 후 콜백을 받을 URL을 제한할 수 있도록 도메인을 설정할 수 있습니다. callback 주소가 설정된 도메인 주소가 아닐 때 접근을 제한합니다. 이 때 등록될 도메인은 반드시 소유권을 가지고 있는 주소여야 합니다. 그렇지 않으면 등록이 안됩니다. 저는 로컬에서 모든 것을 해결할 것이므로 패스..

 


 여기까지 설정했다면 Calendar API를 사용하기 위한 준비가 끝났습니다. 이제 Spring Boot Project 설정을 보겠습니다!.




기본 설정 부분은 구글에서 제공하는 java quick start를 보셔도 됩니다!.


Dependency


 구글 API 사용을 위한 구글 API 라이브러리, oauth 인증을 위한 라이브러리, calendar 서비스를 위한 라이브러리를 추가했습니다!

1
2
3
compile ('com.google.api-client:google-api-client:1.20.0')
compile ('com.google.oauth-client:google-oauth-client-jetty:1.20.0')
compile ('com.google.apis:google-api-services-calendar:v3-rev125-1.20.0')
cs




AuthUtil


 다음이 바로 구글 Oauth 인증을 통해 Calendar 서비스를 생성하는 과정입니다. 저는 Calendar 서비스를 생성하는 과정까지를 Util로 따로 분리하여 작성하였습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class AuthCalendarUtil {
    private static final String APPLICATION_NAME = "Google Calendar API Java Quickstart";
 
    private static final java.io.File DATA_STORE_DIR = new java.io.File(
            System.getProperty("user.home"), ".credentials/calendar-ultron.json");
 
    private static FileDataStoreFactory DATA_STORE_FACTORY;
 
    private static final JsonFactory JSON_FACTORY =
            JacksonFactory.getDefaultInstance();    
 
    private static final List<String> SCOPES =
            Arrays.asList(CalendarScopes.CALENDAR_READONLY);

private static HttpTransport HTTP_TRANSPORT;
 
    static {
        try {
            HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
            DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
        } catch (Throwable t) {
            t.printStackTrace();
            System.exit(1);
        }
    }
cs
  • APPLICATION_NAME : 서비스의 이름이니 원하는 이름으로 작성하면 됩니다.

  • DATA_STORE_DIR : DATA_STORE_FACTORY에서 구글 Oauth 인증 정보가 저장되는 경로를 말합니다. 위의 설정은 User의 HOME으로 지정된 디렉토리의 .crdentials이란 디렉토리에 calendar-ultron.json이란 파일을 뜻 합니다.

  • JSON_FACTORY : client_secret.json을 구글 API에 맞게 파싱해주는 구글 API 라이브러리에 포함된 JacksonFacotry입니다. 

  • SCOPES :  해당 계정에게 요구되는 권한으로 계정에서 Oauth 동의 화면에서 승인하게 되는 내용입니다. CALENDAR_READONLY는 읽기만 하겠다는 것을 뜻합니다. Google API 문서에서 다른 SCOPE를 확인 가능합니다.

  • HTTP_TRANSPORT : Google API 통신을 위한 HTTP TRANSPORT입니다.

  • DATA_STORE_FACTORY : DATA_STORE_DIR로 지정된 파일이 없는 경우에 구글 Oauth 인증 절차를 진행하여 해당 파일을 생성하며, 파일이 있는 경우 파일 안의 인증 정보로 인증을 갱신합니다.



 다음으로 구글 인증 위의 설정 정보를 이용하여 구글 인증을 획득하는 과정입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    public static Credential authorize() throws IOException, GeneralSecurityException {
        // Load client secrets.
        InputStream in =
                AuthCalendarUtil.class.getResourceAsStream("/client_secret.json");
        GoogleClientSecrets clientSecrets =
                GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
 
        // Build flow and trigger user authorization request.
        GoogleAuthorizationCodeFlow flow =
                new GoogleAuthorizationCodeFlow.Builder(
                        HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                        .setDataStoreFactory(DATA_STORE_FACTORY)
                        .setAccessType("offline")
                        .build();
        Credential credential = new AuthorizationCodeInstalledApp(
                flow, new LocalServerReceiver()).authorize("user");
        System.out.println(
                "Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
        return credential;
    }
cs


 2~6 : JSON_FACTORY를 사용하여 client_secret을 GoogleClientSecrets로 맵핑합니다. 

9~14 : 설정했던 HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES, DATA_STORE_FACTORY를 이용하여 flow를 빌드!


setAccessType : offline 모드는 온라인상 로그인, 로그아웃과 별개의 토큰을 생성하여 인증을 관리하는 설정이며 디폴트는 online 입니다. online 설정시 온라인 로그아웃시 

토큰이 만료되어 해당 서비스에서도 인증이 안되게 됩니다. 한번 인증으로 계속 사용을 원할 시에는 offline 모드로 합니다. 저 같은 경우는 봇에 띄울 인증이기 때문에 offline 모드로 했습니다. 더 정확한 내용은 API 문서 참고하시면 됩니다!



인증 구동 해보기


 봇에서 작성한 인증을 구동해보면



 위 사진과 같이 콘솔창에 해당 URL로 인증하라는 메시지가 나옵니다. 해당 URL로 들어가서 로그인을 하면

 설정해두었던 client_secret이 OAuth 2.0 클라이언트 ID 를 읽어 설정해두었던 서비스 계정인 '울트론'이 보입니다. 내 캘린더를 봅니다는 SCOPE로 지정했던 값으로 사용자의 동의를 받게 됩니다. 허용을 클릭하면 



 callback url로 토큰 정보 파라미터를 포함하여 해당 서비스로 인증 정보를 보냅니다. 저 같은 경우는 봇을 띄운 서버는 VM 가상서버여서 callback된 URL을 복사하여 VM 내에서 curl을 사용하여 해당 서비스로 보냈습니다.


 여기까지 완료되면 인증 과정이 끝나고 System.out으로 설정해놓은데로 해당 파일이 어디에 저장되었는지 콘솔로 출력이 됩니다. 


 

 다음 구동시부터는 해당 경로에 해당 파일이 있고 유효하다면 위와 같은 과정을 거치지않고 바로 인증이 됩니다.

댓글
댓글쓰기 폼