https://developers.google.com/sheets/api 를 사용하여 비공개(private) Google Sheet 에 접근해야할 때, 인증부분에서 겪은 삽질을 공유한다.
먼저 알아야 할 것은 API KEY로 접근하는 것은 공개(public) sheet 만 read-only 권한으로 가능하다. 그 이외의 접근에는 API KEY를 사용할 수 없다.
비공개 sheet에 접근할 때는 Google Cloud Platform 에서 발급할 수 있는 서비스 계정(Service Account)이 필요하다.
Google Sheet를 접근하고자 하는 프로젝트로 이동하여 API 및 서비스
> 라이브러리
메뉴를 선택한다.
Google Sheet API를 검색한 후 사용설정
을 한다. 그 후 관리
버튼을 눌러 서비스 계정을 생성한다.
사용자 인증 정보
를 선택한다.
그 후 + 사용자 인증 정보 만들기
를 선택하고 서비스 계정
을 선택한다.
서비스 계정 이름
과 서비스 계정 ID
를 입력하고 완료
버튼을 누른다. 서비스 계정 ID가 중요하다. 나중에 문서 공유를 설정할 때, 여기에서 생성한 이메일이 필요하기 때문이다.
서비스 계정 생성이 완료되면 해당 서비스 계정을 선택하여 상세 화면으로 진입한다. 그리고 키
메뉴를 선택하고 키 추가
> 새 키 만들기
를 선택한다.
이어 나오는 모달 화면에서 JSON
을 선택하면 서비스 계정 키가 JSON 형식으로 생성되고 로컬 컴퓨터로 다운로드 된다.
해당 파일에는 아래와 같은 정보가 포함되어 있다.
{
"type": "service_account",
"project_id": "...",
"private_key_id": "...",
"private_key": "...",
"client_email": "my-google-sheet-bot@youtext-dashboard.iam.gserviceaccount.com",
"client_id": "...",
"auth_uri": "...",
"token_uri": "...",
"auth_provider_x509_cert_url": "...",
"client_x509_cert_url": "..."
}
위 정보를 바탕으로 google-spreadsheet 라이브러를 사용하여 문서에 접근해 보자.
const creds = require('./my-project-service-account-key.json');
const { GoogleSpreadsheet } = require('google-spreadsheet');
(async () => {
try {
// Initialize the sheet - doc ID is the long id in the sheets URL
const doc = new GoogleSpreadsheet('Google Sheet ID');
await doc.useServiceAccountAuth(creds);
await doc.loadInfo();
console.log(doc.title);
} catch (error) {
console.log(error.message);
}
})();
실행해 보면 Google API error - [403] The caller does not have permission
오류가 발생한다.
그 이유는 Google Sheet 에 접근하기 위해서는 위 서비스 계정과 문서를 공유해야 하기 때문이다. API 접근하려는 Google Sheet로 이동한다.
문서에서 공유
버튼을 누른다.
사용자 및 그룹 추가
란에 서비스 계정의 이메일을 추가한다.
보내기
버튼을 눌러 공유를 완료한다.
사용자 및 그룹과 공유
에 방금 추가한 서비스 계정이 추가되었음을 알 수 있다. 필요에 따라 공유 타입을 뷰어
, 댓글 작성자
, 편집자
중에 하나로 변경한다.
이제 다시 아래 코드를 실행해 보자.
const creds = require('./my-project-service-account-key.json');
const { GoogleSpreadsheet } = require('google-spreadsheet');
(async () => {
try {
// Initialize the sheet - doc ID is the long id in the sheets URL
const doc = new GoogleSpreadsheet('Google Sheet ID');
await doc.useServiceAccountAuth(creds);
await doc.loadInfo();
console.log(doc.title);
} catch (error) {
console.log(error.message);
}
})();
$ node index.js
테스트용
문서의 제목이 출력됨을 확인할 수 있다.