이 가이드에서는 앱이 사용자 머신에 설치될 때 BigQuery API에 액세스하기 위해 사용자 계정을 사용하여 인증하는 방법을 설명합니다.
앱이 최종 사용자가 사용할 수 있는 BigQuery 테이블에만 액세스하도록 하기위해 사용자 인증 정보를 사용하여 인증합니다. 사용자 인증 정보는 앱의 프로젝트가 아니라 최종 사용자의 Google Cloud 프로젝트에 대해서만 쿼리를 실행할 수 있습니다. 따라서 앱이 아닌 쿼리를 기준으로 사용자에게 비용이 청구됩니다.
importcom.google.api.client.auth.oauth2.Credential;importcom.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;importcom.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;importcom.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;importcom.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;importcom.google.api.client.googleapis.javanet.GoogleNetHttpTransport;importcom.google.api.client.json.JsonFactory;importcom.google.api.client.json.jackson2.JacksonFactory;importcom.google.api.client.util.store.FileDataStoreFactory;importcom.google.api.gax.paging.Page;importcom.google.auth.oauth2.GoogleCredentials;importcom.google.auth.oauth2.UserCredentials;importcom.google.cloud.bigquery.BigQuery;importcom.google.cloud.bigquery.BigQueryException;importcom.google.cloud.bigquery.BigQueryOptions;importcom.google.cloud.bigquery.Dataset;importcom.google.common.collect.ImmutableList;importjava.io.File;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.nio.file.Files;importjava.nio.file.Path;importjava.nio.file.Paths;importjava.security.GeneralSecurityException;importjava.util.List;// Sample to authenticate by using a user credentialpublicclassAuthUserFlow{privatestaticfinalFileDATA_STORE_DIR=newFile(AuthUserFlow.class.getResource("/").getPath(),"credentials");privatestaticfinalJsonFactoryJSON_FACTORY=JacksonFactory.getDefaultInstance();// i.e redirect_uri http://localhost:61984/CallbackprivatestaticfinalintLOCAL_RECEIVER_PORT=61984;publicstaticvoidrunAuthUserFlow(){// TODO(developer): Replace these variables before running the sample./** * Download your OAuth2 configuration from the Google Developers Console API Credentials page. * https://console.cloud.google.com/apis/credentials */PathcredentialsPath=Paths.get("path/to/your/client_secret.json");List<String>scopes=ImmutableList.of("https://www.googleapis.com/auth/bigquery");authUserFlow(credentialsPath,scopes);}publicstaticvoidauthUserFlow(PathcredentialsPath,List<String>selectedScopes){// Reading credentials filetry(InputStreaminputStream=Files.newInputStream(credentialsPath)){// Load client_secret.json fileGoogleClientSecretsclientSecrets=GoogleClientSecrets.load(JSON_FACTORY,newInputStreamReader(inputStream));StringclientId=clientSecrets.getDetails().getClientId();StringclientSecret=clientSecrets.getDetails().getClientSecret();// Generate the url that will be used for the consent dialog.GoogleAuthorizationCodeFlowflow=newGoogleAuthorizationCodeFlow.Builder(GoogleNetHttpTransport.newTrustedTransport(),JSON_FACTORY,clientSecrets,selectedScopes).setDataStoreFactory(newFileDataStoreFactory(DATA_STORE_DIR)).setAccessType("offline").setApprovalPrompt("auto").build();// Exchange an authorization code for refresh tokenLocalServerReceiverreceiver=newLocalServerReceiver.Builder().setPort(LOCAL_RECEIVER_PORT).build();Credentialcredential=newAuthorizationCodeInstalledApp(flow,receiver).authorize("user");// OAuth2 Credentials representing a user's identity and consentGoogleCredentialscredentials=UserCredentials.newBuilder().setClientId(clientId).setClientSecret(clientSecret).setRefreshToken(credential.getRefreshToken()).build();// Initialize client that will be used to send requests. This client only needs to be created// once, and can be reused for multiple requests.BigQuerybigquery=BigQueryOptions.newBuilder().setCredentials(credentials).build().getService();Page<Dataset>datasets=bigquery.listDatasets(BigQuery.DatasetListOption.pageSize(100));if(datasets==null){System.out.println("Dataset does not contain any models");return;}datasets.iterateAll().forEach(dataset->System.out.printf("Success! Dataset ID: %s ",dataset.getDatasetId()));}catch(BigQueryException|IOException|GeneralSecurityExceptionex){System.out.println("Project does not contain any datasets \n"+ex.toString());}}}
Python
fromgoogle_auth_oauthlibimportflow# A local server is used as the callback URL in the auth flow.appflow=flow.InstalledAppFlow.from_client_secrets_file("client_secrets.json",scopes=["https://www.googleapis.com/auth/bigquery"])# This launches a local server to be used as the callback URL in the desktop# app auth flow. If you are accessing the application remotely, such as over# SSH or a remote Jupyter notebook, this flow will not work. Use the# `gcloud auth application-default login --no-browser` command or workload# identity federation to get authentication tokens, instead.#appflow.run_local_server()credentials=appflow.credentials
Node.js
const{OAuth2Client}=require('google-auth-library');constreadline=require('readline-promise').default;functionstartRl(){constrl=readline.createInterface({input:process.stdin,output:process.stdout,});returnrl;}/** * Download your OAuth2 configuration from the Google * Developers Console API Credentials page. * https://console.cloud.google.com/apis/credentials */constkeys=require('./oauth2.keys.json');/** * Create a new OAuth2Client, and go through the OAuth2 content * workflow. Return the full client to the callback. */asyncfunctiongetRedirectUrl(){constrl=main.startRl();// Create an oAuth client to authorize the API call. Secrets are kept in a `keys.json` file,// which should be downloaded from the Google Developers Console.constoAuth2Client=newOAuth2Client(keys.installed.client_id,keys.installed.client_secret,keys.installed.redirect_uris[0]);// Generate the url that will be used for the consent dialog.constauthorizeUrl=oAuth2Client.generateAuthUrl({access_type:'offline',scope:'https://www.googleapis.com/auth/bigquery',prompt:'consent',});console.info(`Please visit this URL to authorize this application: ${authorizeUrl}`);constcode=awaitrl.questionAsync('Enter the authorization code: ');consttokens=awaitmain.exchangeCode(code);rl.close();returntokens;}// Exchange an authorization code for an access tokenasyncfunctionexchangeCode(code){constoAuth2Client=newOAuth2Client(keys.installed.client_id,keys.installed.client_secret,keys.installed.redirect_uris[0]);constr=awaitoAuth2Client.getToken(code);console.info(r.tokens);returnr.tokens;}asyncfunctionauthFlow(projectId='project_id'){/** * TODO(developer): * Save Project ID as environment variable PROJECT_ID="project_id" * Uncomment the following line before running the sample. */// projectId = process.env.PROJECT_ID;consttokens=awaitmain.getRedirectUrl();constcredentials={type:'authorized_user',client_id:keys.installed.client_id,client_secret:keys.installed.client_secret,refresh_token:tokens.refresh_token,};return{projectId,credentials,};}
인증된 사용자 인증 정보를 사용하여 BigQuery API에 연결합니다.
Java
importcom.google.api.client.auth.oauth2.Credential;importcom.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;importcom.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;importcom.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;importcom.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;importcom.google.api.client.googleapis.javanet.GoogleNetHttpTransport;importcom.google.api.client.json.JsonFactory;importcom.google.api.client.json.jackson2.JacksonFactory;importcom.google.api.client.util.store.FileDataStoreFactory;importcom.google.auth.oauth2.GoogleCredentials;importcom.google.auth.oauth2.UserCredentials;importcom.google.cloud.bigquery.BigQuery;importcom.google.cloud.bigquery.BigQueryException;importcom.google.cloud.bigquery.BigQueryOptions;importcom.google.cloud.bigquery.QueryJobConfiguration;importcom.google.cloud.bigquery.TableResult;importcom.google.common.collect.ImmutableList;importjava.io.File;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.nio.file.Files;importjava.nio.file.Path;importjava.nio.file.Paths;importjava.security.GeneralSecurityException;importjava.util.List;// Sample to query by using a user credentialpublicclassAuthUserQuery{privatestaticfinalFileDATA_STORE_DIR=newFile(AuthUserQuery.class.getResource("/").getPath(),"credentials");privatestaticfinalJsonFactoryJSON_FACTORY=JacksonFactory.getDefaultInstance();// i.e redirect_uri http://localhost:61984/CallbackprivatestaticfinalintLOCAL_RECEIVER_PORT=61984;publicstaticvoidrunAuthUserQuery(){// TODO(developer): Replace these variables before running the sample./** * Download your OAuth2 configuration from the Google Developers Console API Credentials page. * https://console.cloud.google.com/apis/credentials */PathcredentialsPath=Paths.get("path/to/your/client_secret.json");List<String>scopes=ImmutableList.of("https://www.googleapis.com/auth/bigquery");Stringquery="SELECT name, SUM(number) as total"+" FROM `bigquery-public-data.usa_names.usa_1910_current`"+" WHERE name = 'William'"+" GROUP BY name;";authUserQuery(credentialsPath,scopes,query);}publicstaticvoidauthUserQuery(PathcredentialsPath,List<String>selectedScopes,Stringquery){// Reading credentials filetry(InputStreaminputStream=Files.newInputStream(credentialsPath)){// Load client_secret.json fileGoogleClientSecretsclientSecrets=GoogleClientSecrets.load(JSON_FACTORY,newInputStreamReader(inputStream));StringclientId=clientSecrets.getDetails().getClientId();StringclientSecret=clientSecrets.getDetails().getClientSecret();// Generate the url that will be used for the consent dialog.GoogleAuthorizationCodeFlowflow=newGoogleAuthorizationCodeFlow.Builder(GoogleNetHttpTransport.newTrustedTransport(),JSON_FACTORY,clientSecrets,selectedScopes).setDataStoreFactory(newFileDataStoreFactory(DATA_STORE_DIR)).setAccessType("offline").setApprovalPrompt("auto").build();// Exchange an authorization code for refresh tokenLocalServerReceiverreceiver=newLocalServerReceiver.Builder().setPort(LOCAL_RECEIVER_PORT).build();Credentialcredential=newAuthorizationCodeInstalledApp(flow,receiver).authorize("user");// OAuth2 Credentials representing a user's identity and consentGoogleCredentialscredentials=UserCredentials.newBuilder().setClientId(clientId).setClientSecret(clientSecret).setRefreshToken(credential.getRefreshToken()).build();// Initialize client that will be used to send requests. This client only needs to be created// once, and can be reused for multiple requests.BigQuerybigquery=BigQueryOptions.newBuilder().setCredentials(credentials).build().getService();QueryJobConfigurationqueryConfig=QueryJobConfiguration.newBuilder(query).build();TableResultresults=bigquery.query(queryConfig);results.iterateAll().forEach(row->row.forEach(val->System.out.printf("%s,",val.toString())));System.out.println("Query performed successfully.");}catch(BigQueryException|IOException|GeneralSecurityException|InterruptedExceptionex){System.out.println("Query not performed \n"+ex.toString());}}}
Python
fromgoogle.cloudimportbigquery# TODO: Uncomment the line below to set the `project` variable.# project = 'user-project-id'## The `project` variable defines the project to be billed for query# processing. The user must have the bigquery.jobs.create permission on# this project to run a query. See:# https://cloud.google.com/bigquery/docs/access-control#permissionsclient=bigquery.Client(project=project,credentials=credentials)query_string="""SELECT name, SUM(number) as totalFROM `bigquery-public-data.usa_names.usa_1910_current`WHERE name = 'William'GROUP BY name;"""results=client.query_and_wait(query_string)# Print the results.forrowinresults:# Wait for the job to complete.print("{}: {}".format(row["name"],row["total"]))
Node.js
asyncfunctionquery(){const{BigQuery}=require('@google-cloud/bigquery');constcredentials=awaitmain.authFlow();constbigquery=newBigQuery(credentials);// Queries the U.S. given names dataset for the state of Texas.constquery=`SELECT name, SUM(number) as total FROM \`bigquery-public-data.usa_names.usa_1910_current\` WHERE name = 'William' GROUP BY name;`;// For all options, see https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/queryconstoptions={query:query,};// Run the query as a jobconst[job]=awaitbigquery.createQueryJob(options);console.log(`Job ${job.id} started.`);// Wait for the query to finishconst[rows]=awaitjob.getQueryResults();// Print the resultsconsole.log('Rows:');rows.forEach(row=>console.log(row));returnrows;}constmain={query,authFlow,exchangeCode,getRedirectUrl,startRl,};module.exports={main,};if(module===require.main){query().catch(console.error);}
샘플 코드를 실행하면 클라이언트 보안 비밀번호와 연결된 프로젝트의 액세스를 요청하는 브라우저가 시작됩니다. 샘플이 BigQuery 범위를 요청했으므로, 결과 사용자 인증 정보를 통해 사용자의 BigQuery 리소스에 액세스할 수 있습니다.
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["이해하기 어려움","hardToUnderstand","thumb-down"],["잘못된 정보 또는 샘플 코드","incorrectInformationOrSampleCode","thumb-down"],["필요한 정보/샘플이 없음","missingTheInformationSamplesINeed","thumb-down"],["번역 문제","translationIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-03-31(UTC)"],[[["This guide demonstrates how to authenticate installed applications to access the BigQuery API using user credentials, ensuring that only tables accessible to the end user can be queried."],["User credentials allow apps to run queries against the user's Google Cloud project, resulting in the user being billed for queries instead of the app."],["Before authenticating, you will need to create a Google Cloud project for the installed app, install the BigQuery client libraries, and install authentication libraries, which are provided for Java, Python, and Node.js."],["Setting up client credentials involves creating an OAuth client ID of the Desktop app type, and downloading a `client_secrets.json` file which contains the credentials that will need to be distributed with your app."],["The process of authenticating and calling the API involves performing the OAuth 2.0 flow using the downloaded client credentials, then using these authenticated credentials to connect and query the BigQuery API, as showcased in code samples for Java, Python, and Node.js."]]],[]]