웹 앱용 코드 샘플
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
이 가이드에서는 다중 선택 사용 설정, 탐색 창 숨기기, 앱의 현재 OAuth 2.0 토큰으로 사용자 계정 선택과 같은 Google Picker API 기능을 사용하는 방법을 설명합니다.
기본 요건
이 예에서는 다음 항목을 지정해야 합니다.
사용자의 파일에 대한 액세스를 승인하는 데 사용되므로 동일한 Google Cloud 프로젝트에 클라이언트 ID와 앱 ID가 모두 포함되어야 합니다.
앱 만들기
다음 코드 샘플은 사용자가 웹 앱의 버튼에서 열 수 있는 이미지 선택기 또는 업로드 페이지를 사용하는 방법을 보여줍니다.
setOAuthToken
함수를 사용하면 앱이 현재 인증 토큰을 사용하여 Google 선택기에서 파일을 표시하는 데 사용하는 Google 계정을 확인할 수 있습니다. 사용자가 여러 Google 계정으로 로그인한 경우 Google 선택 도구는 적절한 승인된 계정의 파일을 표시할 수 있습니다.
파일을 열 때 Google Picker에서 파일 ID를 가져온 후 앱은 files
리소스의 get
메서드에 설명된 대로 파일 메타데이터를 가져오고 파일 콘텐츠를 다운로드할 수 있습니다.
달리 명시되지 않는 한 이 페이지의 콘텐츠에는 Creative Commons Attribution 4.0 라이선스에 따라 라이선스가 부여되며, 코드 샘플에는 Apache 2.0 라이선스에 따라 라이선스가 부여됩니다. 자세한 내용은 Google Developers 사이트 정책을 참조하세요. 자바는 Oracle 및/또는 Oracle 계열사의 등록 상표입니다.
최종 업데이트: 2025-08-29(UTC)
[null,null,["최종 업데이트: 2025-08-29(UTC)"],[],[],null,["# Code sample for web apps\n\nThis guide explains how to use Google Picker API features such as turning on\nmulti-select, hiding the navigation pane, and choosing the user account with the\napp's current OAuth 2.0 token.\n| **Note:** You can also use the [`@googleworkspace/drive-picker-element`](https://npmjs.com/package/@googleworkspace/drive-picker-element) web component to integrate the Google Picker into your web app.\n\nPrerequisites\n-------------\n\nFor this example, you need to specify several items:\n\n- To locate both the **Client ID** and the **API Key**:\n\n 1. In the Google Cloud console, go to Menu\n menu\n \\\u003e **APIs \\& Services**\n \\\u003e **Credentials**.\n\n [Go to Credentials](https://console.cloud.google.com/apis/credentials)\n- To locate the **App ID**:\n\n 1. In the Google Cloud console, go to Menu\n menu\n \\\u003e **IAM \\& Admin**\n \\\u003e **Settings**.\n\n [Go to Settings](https://console.cloud.google.com/iam-admin/settings)\n 2. Use the **project number** for the app ID.\n\nThe same Google Cloud project must contain both the client ID and the app ID as it's\nused to authorize access to a user's files.\n\nCreate the app\n--------------\n\nThe following code sample shows how to use an image selector or upload page that\nusers can open from a button in a web app. \ndrive/picker/helloworld.html \n[View on GitHub](https://github.com/googleworkspace/browser-samples/blob/main/drive/picker/helloworld.html) \n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n \u003ctitle\u003eGoogle Picker API Quickstart\u003c/title\u003e\n \u003cmeta charset=\"utf-8\" /\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n\u003cp\u003eGoogle Picker API Quickstart\u003c/p\u003e\n\n\u003c!--Add buttons to initiate auth sequence and sign out.--\u003e\n\u003cbutton id=\"authorize_button\" onclick=\"handleAuthClick()\"\u003eAuthorize\u003c/button\u003e\n\u003cbutton id=\"signout_button\" onclick=\"handleSignoutClick()\"\u003eSign Out\u003c/button\u003e\n\n\u003cpre id=\"content\" style=\"white-space: pre-wrap;\"\u003e\u003c/pre\u003e\n\n\u003cscript type=\"text/javascript\"\u003e\n /* exported gapiLoaded */\n /* exported gisLoaded */\n /* exported handleAuthClick */\n /* exported handleSignoutClick */\n\n // Authorization scopes required by the API; multiple scopes can be\n // included, separated by spaces.\n const SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly';\n\n // TODO(developer): Replace with your client ID and API key from https://console.cloud.google.com/.\n const CLIENT_ID = '\u003cYOUR_CLIENT_ID\u003e';\n const API_KEY = '\u003cYOUR_API_KEY\u003e';\n\n // TODO(developer): Replace with your project number from https://console.cloud.google.com/.\n const APP_ID = '\u003cYOUR_APP_ID\u003e';\n\n let tokenClient;\n let accessToken = null;\n let pickerInited = false;\n let gisInited = false;\n\n document.getElementById('authorize_button').style.visibility = 'hidden';\n document.getElementById('signout_button').style.visibility = 'hidden';\n\n /**\n * Callback after api.js is loaded.\n */\n function gapiLoaded() {\n gapi.load('client:picker', initializePicker);\n }\n\n /**\n * Callback after the API client is loaded. Loads the\n * discovery doc to initialize the API.\n */\n async function initializePicker() {\n await gapi.client.load('https://www.googleapis.com/discovery/v1/apis/drive/v3/rest');\n pickerInited = true;\n maybeEnableButtons();\n }\n\n /**\n * Callback after Google Identity Services are loaded.\n */\n function gisLoaded() {\n tokenClient = google.accounts.oauth2.initTokenClient({\n client_id: CLIENT_ID,\n scope: SCOPES,\n callback: '', // defined later\n });\n gisInited = true;\n maybeEnableButtons();\n }\n\n /**\n * Enables user interaction after all libraries are loaded.\n */\n function maybeEnableButtons() {\n if (pickerInited && gisInited) {\n document.getElementById('authorize_button').style.visibility = 'visible';\n }\n }\n\n /**\n * Sign in the user upon button click.\n */\n function handleAuthClick() {\n tokenClient.callback = async (response) =\u003e {\n if (response.error !== undefined) {\n throw (response);\n }\n accessToken = response.access_token;\n document.getElementById('signout_button').style.visibility = 'visible';\n document.getElementById('authorize_button').innerText = 'Refresh';\n await createPicker();\n };\n\n if (accessToken === null) {\n // Prompt the user to select a Google Account and ask for consent to share their data\n // when establishing a new session.\n tokenClient.requestAccessToken({prompt: 'consent'});\n } else {\n // Skip display of account chooser and consent dialog for an existing session.\n tokenClient.requestAccessToken({prompt: ''});\n }\n }\n\n /**\n * Sign out the user upon button click.\n */\n function handleSignoutClick() {\n if (accessToken) {\n google.accounts.oauth2.revoke(accessToken);\n accessToken = null;\n document.getElementById('content').innerText = '';\n document.getElementById('authorize_button').innerText = 'Authorize';\n document.getElementById('signout_button').style.visibility = 'hidden';\n }\n }\n\n /**\n * Create and render a Google Picker object for searching images.\n */\n function createPicker() {\n const view = new google.picker.View(google.picker.ViewId.DOCS);\n view.setMimeTypes('image/png,image/jpeg,image/jpg');\n const picker = new google.picker.PickerBuilder()\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .setDeveloperKey(API_KEY)\n .setAppId(APP_ID)\n .setOAuthToken(accessToken)\n .addView(view)\n .addView(new google.picker.DocsUploadView())\n .setCallback(pickerCallback)\n .build();\n picker.setVisible(true);\n }\n\n /**\n * Displays the file details of the user's selection.\n * @param {object} data - Contains the user selection from the Google Picker.\n */\n async function pickerCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n let text = `Google Picker response: \\n${JSON.stringify(data, null, 2)}\\n`;\n const document = data[google.picker.Response.DOCUMENTS][0];\n const fileId = document[google.picker.Document.ID];\n console.log(fileId);\n const res = await gapi.client.drive.files.get({\n 'fileId': fileId,\n 'fields': '*',\n });\n text += `Drive API response for first document: \\n${JSON.stringify(res.result, null, 2)}\\n`;\n window.document.getElementById('content').innerText = text;\n }\n }\n\u003c/script\u003e\n\u003cscript async defer src=\"https://apis.google.com/js/api.js\" onload=\"gapiLoaded()\"\u003e\u003c/script\u003e\n\u003cscript async defer src=\"https://accounts.google.com/gsi/client\" onload=\"gisLoaded()\"\u003e\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nThe `setOAuthToken` function allows an app to use the current auth token to\ndetermine which Google Account the Google Picker uses to display the files. If\na user is signed in with multiple Google Accounts, the Google Picker can\ndisplay the files of the appropriate authorized account.\n\nAfter obtaining the file ID from the Google Picker when opening files, an app\ncan then fetch the file metadata and download the file content as described in\nthe [`get`](/workspace/drive/api/reference/rest/v3/files/get) method of the [`files`](/workspace/drive/api/reference/rest/v3/files) resource."]]