Bagaimana cara mengotentikasi Google API (Google Drive API) dari Google Compute Engine dan secara lokal tanpa mengunduh kredensial Akun Layanan?
Perusahaan kami sedang mengerjakan pemrosesan data dari Google Sheets (dalam Google Drive) dari Google Cloud Platform dan kami mengalami beberapa masalah dengan autentikasi.
Ada dua tempat berbeda di mana kami perlu menjalankan kode yang membuat panggilan API ke Google Drive: dalam produksi di Google Compute Engine, dan dalam lingkungan pengembangan, yaitu secara lokal di laptop pengembang kami.
Perusahaan kami sangat ketat tentang kredensial dan tidak mengizinkan pengunduhan kunci JSON kredensial Akun Layanan (ini adalah praktik yang lebih baik dan memberikan keamanan yang lebih tinggi). Tampaknya semua dokumen dari GCP mengatakan untuk cukup mendownload kunci JSON untuk Akun Layanan dan menggunakannya. Atau dokumen Google API / Pengembang mengatakan untuk membuat ID Klien OAuth2 dan mengunduh kuncinya seperti di sini .
Mereka sering menggunakan kode seperti ini:
from google.oauth2 import service_account
SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
Tetapi kami tidak dapat (atau hanya tidak ingin) mengunduh kunci JSON Akun Layanan kami, jadi kami macet jika kami hanya mengikuti dokumen.
Untuk lingkungan Mesin Hitung Google, kami dapat mengautentikasi dengan menggunakan Kredensial Default Aplikasi (ADC) GCP - yaitu tidak secara eksplisit menentukan kredensial yang akan digunakan dalam kode dan membiarkan pustaka klien "berfungsi" - ini berfungsi dengan baik selama seseorang memastikan bahwa VM dibuat dengan cakupan yang benar https://www.googleapis.com/auth/drive
, dan email Akun Layanan komputasi default diberi izin ke Sheet yang perlu diakses - ini dijelaskan dalam dokumen di sini . Anda dapat melakukan ini seperti itu;
from googleapiclient.discovery import build
service = build('sheets', 'v4')
SPREADSHEET_ID="<sheet_id>"
RANGE_NAME="A1:A2"
s = service.spreadsheets().values().get(
spreadsheetId=SPREADSHEET_ID,
range=RANGE_NAME, majorDimension="COLUMNS"
).execute()
Namun, bagaimana kami melakukan ini untuk pengembangan, yaitu secara lokal di laptop pengembang kami? Sekali lagi, tanpa mengunduh kunci JSON apa pun, dan lebih disukai dengan pendekatan "langsung berfungsi" sebanyak mungkin?
Biasanya kami menggunakan gcloud auth application-default login
untuk membuat kredensial aplikasi default yang digunakan perpustakaan klien Google yang "berfungsi", seperti untuk Google Storage. Namun, ini tidak berfungsi untuk Google API di luar GCP, seperti Google Drive API service = build('sheets', 'v4')
yang gagal dengan kesalahan ini: "Permintaan memiliki cakupan autentikasi yang tidak memadai.". Kemudian kami mencoba semua jenis solusi seperti:
credentials, project_id = google.auth.default(scopes=["https://www.googleapis.com/auth/drive"])
dan
credentials, project_id = google.auth.default()
credentials = google_auth_oauthlib.get_user_credentials(
["https://www.googleapis.com/auth/drive"], credentials._client_id, credentials._client_secret)
)
dan banyak lagi ... Yang semuanya memberikan segudang kesalahan / masalah yang tidak dapat kami lewati saat mencoba melakukan otentikasi ke Google Drive API :(
Ada pemikiran?
Jawaban
Salah satu metode untuk mempermudah autentikasi dari lingkungan pengembangan adalah menggunakan peniruan Akun Layanan .
Berikut adalah blog tentang penggunaan peniruan akun layanan, termasuk manfaat melakukannya. @johnhanley (yang menulis posting blog) adalah pria yang hebat dan memiliki banyak jawaban yang sangat informatif tentang SO juga!
Agar mesin lokal Anda dapat mengautentikasi untuk API Google Drive, Anda perlu membuat kredensial aplikasi default di komputer lokal Anda yang meniru Akun Layanan dan menerapkan cakupan yang diperlukan untuk API yang ingin Anda akses.
Untuk dapat meniru Akun Layanan, pengguna Anda harus memiliki peran tersebut roles/iam.serviceAccountTokenCreator
. Peran ini dapat diterapkan ke seluruh proyek atau ke Akun Layanan individu.
Anda dapat menggunakan gclouduntuk melakukan ini:
gcloud iam service-accounts add-iam-policy-binding [COMPUTE_SERVICE_ACCOUNT_FULL_EMAIL] \
--member user:[USER_EMAIL] \
--role roles/iam.serviceAccountTokenCreator
Setelah ini selesai buat kredensial lokal:
gcloud auth application-default login \
--scopes=https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/accounts.reauth \
--impersonate-service-account=[COMPUTE_SERVICE_ACCOUNT_FULL_EMAIL]
Ini akan menyelesaikan kesalahan cakupan yang Anda dapatkan. Tiga cakupan tambahan yang ditambahkan di luar cakupan API Drive adalah cakupan default yang gcloud auth application-default login
berlaku dan dibutuhkan.
Jika Anda menerapkan cakupan tanpa peniruan identitas, Anda akan mendapatkan pesan kesalahan seperti ini saat mencoba untuk mengautentikasi:
HttpError: <HttpError 403 when requesting https://sheets.googleapis.com/v4/spreadsheets?fields=spreadsheetId&alt=json returned "Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the sheets.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.">
Setelah Anda menyiapkan kredensial, Anda dapat menggunakan kode yang sama yang dijalankan di Google Compute Engine di mesin lokal Anda :)
Catatan: Anda juga dapat menyetel peniruan untuk semua perintah gcloud:
gcloud config set auth/impersonate_service_account [COMPUTE_SERVICE_ACCOUNT_FULL_EMAIL]
Membuat kredentail aplikasi default di komputer lokal Anda dengan meniru akun layanan adalah cara yang apik untuk mengautentikasi kode pengembangan. Artinya, kode tersebut akan memiliki izin yang persis sama dengan Akun Layanan yang ditirunya. Jika ini adalah Akun Layanan yang sama yang akan menjalankan kode dalam produksi, Anda tahu bahwa kode dalam pengembangan berjalan sama dengan produksi. Ini juga berarti Anda tidak perlu membuat atau mengunduh kunci Akun Layanan apa pun.