커뮤니티 커넥터에서 서비스 계정을 사용하여 리소스 액세스를 중앙에서 관리할 수 있습니다. 일반적인 사용 사례는 사용자가 자신의 사용자 인증 정보로는 액세스할 수 없는 데이터에 대한 액세스 권한을 위임하는 것입니다.
서비스 계정 이해 를 검토하여 해당 주제를 숙지합니다.
이점
데이터 액세스를 위해 결제를 통합할 수 있습니다.
커넥터에서 자체 액세스 제어 레이어를 구현할 수 있습니다.
사용자 인증 정보로 액세스할 수 없는 데이터 또는 리소스에 대한 액세스 권한을 위임할 수 있습니다.
구현 단계
데이터를 가져올 플랫폼의 서비스 계정을 만듭니다.
필요한 리소스에 액세스할 수 있도록 서비스 계정에 필요한 권한을 제공합니다.
커넥터의 스크립트 속성에 서비스 계정의 사용자 인증 정보를 저장합니다.
커넥터가 실행되는 동안 저장된 사용자 인증 정보를 사용하여 필요한 데이터를 가져옵니다.
선택사항 : 액세스 제어 로직을 구현하여 데이터를 필터링합니다.
주의: 코드에 서비스 계정의 사용자 인증 정보를 저장하지 마세요. 대신 커넥터의 스크립트 속성을 사용하여 Apps Script 또는 외부 코드 저장소를 통해 코드에 대한 보기 액세스 권한이 있는 다른 사용자가 사용자 인증 정보를 볼 수 없도록 하세요.
예: Looker Studio 고급 서비스 및 서비스 계정으로 BigQuery에 액세스
사용자가 BigQuery 테이블에서 대시보드를 빌드하는 솔루션을 빌드하고 있습니다. 사용자가 Looker Studio의 BigQuery 커넥터를 사용하는 경우 BigQuery 테이블에 대한 읽기 액세스 권한이 필요합니다. 또한 Google Cloud Platform (GCP)용 결제 계정이 필요합니다. 다음 단계에서는 서비스 계정을 사용하여 결제를 통합하고 BigQuery 데이터에 대한 액세스 권한을 위임하는 방법을 보여줍니다.
원하는 GCP 프로젝트에서 서비스 계정을 만듭니다 .
서비스 계정이 BigQuery 작업을 만들고 필요한 테이블의 데이터를 볼 수 있는지 확인합니다. 자세한 내용은 BigQuery 액세스 제어 를 참조하세요.
서비스 계정의 키를 만들고 커넥터의 스크립트 속성 에 사용자 인증 정보를 저장합니다.
Apps Script 프로젝트에 OAuth2 Apps Script 라이브러리를 포함합니다.
getData
함수의 경우 서비스 계정을 인증하고 액세스 토큰을 생성합니다. OAuth2 범위를 https://www.googleapis.com/auth/bigquery.readonly
로 설정합니다.
getData
응답에서 다른 구성 항목과 함께 액세스 토큰을 반환합니다.
다음은 커넥터 코드의 전체 예입니다.
main.js
var cc = DataStudioApp.createCommunityConnector();
var scriptProperties = PropertiesService.getScriptProperties();
function isAdminUser() {
return true;
}
function getAuthType() {
var AuthTypes = cc.AuthType;
return cc
.newAuthTypeResponse()
.setAuthType(AuthTypes.NONE)
.build();
}
function getConfig(request) {
var config = cc.getConfig();
config
.newInfo()
.setId('generalInfo')
.setText('This is an example connector to showcase row level security.');
return config.build();
}
function getFields() {
var fields = cc.getFields();
var types = cc.FieldType;
var aggregations = cc.AggregationType;
fields
.newDimension()
.setId('region')
.setName('Region')
.setType(types.TEXT);
fields
.newMetric()
.setId('sales')
.setName('Sales')
.setType(types.NUMBER)
.setAggregation(aggregations.SUM);
fields
.newDimension()
.setId('date')
.setName('Date')
.setType(types.YEAR_MONTH_DAY);
return fields;
}
function getSchema(request) {
return {schema: getFields().build()};
}
var SERVICE_ACCOUNT_CREDS = 'SERVICE_ACCOUNT_CREDS';
var SERVICE_ACCOUNT_KEY = 'private_key';
var SERVICE_ACCOUNT_EMAIL = 'client_email';
var BILLING_PROJECT_ID = 'project_id';
/**
* Copy the entire credentials JSON file from creating a service account in GCP.
*/
function getServiceAccountCreds() {
return JSON.parse(scriptProperties.getProperty(SERVICE_ACCOUNT_CREDS));
}
function getOauthService() {
var serviceAccountCreds = getServiceAccountCreds();
var serviceAccountKey = serviceAccountCreds[SERVICE_ACCOUNT_KEY];
var serviceAccountEmail = serviceAccountCreds[SERVICE_ACCOUNT_EMAIL];
return OAuth2.createService('RowLevelSecurity')
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setPrivateKey(serviceAccountKey)
.setIssuer(serviceAccountEmail)
.setPropertyStore(scriptProperties)
.setCache(CacheService.getScriptCache())
.setScope(['https://www.googleapis.com/auth/bigquery.readonly']);
}
var BASE_SQL =
'SELECT d.region, d.sales, d.date ' +
'FROM `datastudio-solutions.row_level_security.data` d ' +
'INNER JOIN `datastudio-solutions.row_level_security.access` a ' +
'ON d.region = a.region ' +
'where a.email=@email';
function getData(request) {
var accessToken = getOauthService().getAccessToken();
var serviceAccountCreds = getServiceAccountCreds();
var billingProjectId = serviceAccountCreds[BILLING_PROJECT_ID];
var email = Session.getEffectiveUser().getEmail();
var bqTypes = DataStudioApp.createCommunityConnector().BigQueryParameterType;
return cc
.newBigQueryConfig()
.setAccessToken(accessToken)
.setBillingProjectId(billingProjectId)
.setUseStandardSql(true)
.setQuery(BASE_SQL)
.addQueryParameter('email', bqTypes.STRING, email)
.build();
}