Tài khoản dịch vụ

Tài khoản dịch vụ là một loại Tài khoản Google mà ứng dụng có thể dùng để truy cập vào API của Google theo phương thức lập trình thông qua OAuth 2.0. Tính năng này không yêu cầu sự cho phép của con người nhưng thay vào đó sẽ sử dụng tệp khoá mà chỉ ứng dụng của bạn mới có thể truy cập.

Trước khi đọc thêm về tài khoản dịch vụ, hãy xem xét lựa chọn thay thế đơn giản và được đề xuất nhiều trong việc triển khai quy trình cài đặt ứng dụng đã cài đặt OAuth 2.0. Phương pháp này yêu cầu người dùng cho phép ứng dụng tạo mã làm mới theo cách thủ công. Tuy nhiên, bạn chỉ cần thực hiện việc này một lần vì những mã thông báo này không bao giờ hết hạn.

Bạn vẫn đang đọc? Được rồi, bạn có thể triển khai tài khoản dịch vụ theo một trong những cách sau:

  • Nếu người dùng của bạn thuộc nhiều miền, hãy triển khai bằng cách sử dụng tài khoản dịch vụ với tư cách là người dùng Campaign Manager 360. Điều này cho phép bạn kết nối với nhiều tài khoản thuộc sở hữu của các đại lý khác nhau bằng cách tạo hồ sơ người dùng mới trên mỗi tài khoản và liên kết tất cả các tài khoản đó với một tài khoản dịch vụ duy nhất. Đây là cách ưu tiên để sử dụng tài khoản dịch vụ với Campaign Manager 360.
  • Nếu người dùng của bạn sinh sống trên một miền mà bạn sở hữu, hãy triển khai tính năng uỷ quyền trên toàn miền. Trong trường hợp này, bạn phải có quyền quản trị đối với miền đã đăng ký với G Suite. Để được trợ giúp về G Suite và / hoặc cấu hình miền, hãy xem trang hỗ trợ G Suite.

Điều kiện tiên quyết

Để triển khai tài khoản dịch vụ với tư cách là người dùng Campaign Manager 360, hãy chọn thẻ Người dùng Campaign Manager 360. Để triển khai tính năng uỷ quyền trên toàn miền, hãy chọn thẻ Uỷ quyền ở bên dưới.

Người dùng Campaign Manager 360

Bạn phải có quyền truy cập vào một tài khoản Campaign Manager 360 đã bật quyền truy cập vào API.

Uỷ quyền
  1. Bạn phải có quyền truy cập vào một tài khoản Campaign Manager 360 đã bật quyền truy cập vào API.
  2. Bạn phải có quyền quản trị đối với miền đã đăng ký với G Suite.
  3. Bạn phải có hồ sơ người dùng Campaign Manager 360 được liên kết với một hoặc nhiều tài khoản trong miền đã đăng ký G Suite. Những hồ sơ người dùng được liên kết với các tài khoản trong các miền khác, ví dụ như gmail.com, không thể sử dụng.

Định cấu hình và sử dụng tài khoản dịch vụ

Để triển khai bằng tài khoản dịch vụ với tư cách là người dùng Campaign Manager 360, hãy chọn thẻ người dùng Campaign Manager 360. Để triển khai tính năng uỷ quyền trên toàn miền, hãy chọn thẻ Uỷ quyền ở bên dưới.

Người dùng Campaign Manager 360
  1. Tạo khoá tài khoản dịch vụ trong Bảng điều khiển API của Google.

    Thận trọng: Bạn phải bảo vệ tệp khoá cấp quyền truy cập tài khoản dịch vụ vào các dịch vụ của Google mà khoá đó đã được uỷ quyền.
  2. Liên kết hồ sơ người dùng Campaign Manager 360 với email tài khoản dịch vụ nhận được ở bước trước như mô tả trong bài viết Quản lý quyền truy cập của người dùng trên trung tâm trợ giúp.
  3. Triển khai quy trình OAuth 2.0 từ máy chủ đến máy chủ trong ứng dụng của bạn bằng tài khoản dịch vụ mà bạn mới tạo. Để biết thêm thông tin, hãy xem phần ví dụ.
Uỷ quyền
  1. Tạo khoá tài khoản dịch vụ trong Bảng điều khiển API của Google.

    Thận trọng: Bạn phải bảo vệ tệp khoá cấp quyền truy cập tài khoản dịch vụ vào các dịch vụ của Google mà khoá đó đã được uỷ quyền. Điều này đặc biệt đúng với quy trình uỷ quyền trên toàn miền do chế độ kiểm soát cấp miền của G Suite cho phép tài khoản dịch vụ có thể mạo danh bất kỳ người dùng nào trong miền. Bạn cũng nên cho phép các tài khoản dịch vụ chỉ truy cập vào một API của Google (bằng cách sử dụng trường "phạm vi" được mô tả trong bước tiếp theo). Đây là một biện pháp phòng ngừa nhằm giảm thiểu lượng dữ liệu mà kẻ tấn công có thể truy cập trong trường hợp tệp khoá của tài khoản dịch vụ bị xâm phạm.
  2. Uỷ quyền quyền truy cập trên toàn miền cho tài khoản dịch vụ này để cho phép tài khoản mạo danh người dùng trong miền của bạn. Khi được nhắc, hãy cung cấp các phạm vi API sau:
    Phạm vi Ý nghĩa
    https://www.googleapis.com/auth/dfatrafficking Quyền đọc/ghi đối với tính năng quản lý quảng cáo Campaign Manager 360.
    https://www.googleapis.com/auth/dfareporting Quyền đọc/ghi đối với báo cáo Campaign Manager 360.
    https://www.googleapis.com/auth/ddmconversions Quyền đọc/ghi đối với lượt chuyển đổi ngoại tuyến Campaign Manager 360.
  3. Triển khai quy trình OAuth 2.0 từ máy chủ đến máy chủ trong ứng dụng của bạn bằng tài khoản dịch vụ mà bạn mới tạo. Để biết thêm thông tin, hãy xem phần ví dụ. Hãy nhớ rằng bạn cần cung cấp một tài khoản để mạo danh và tài khoản đó phải thuộc về miền mà tài khoản dịch vụ của bạn đã được uỷ quyền trên toàn miền ở bước trước.

Để được trợ giúp về G Suite và / hoặc cấu hình miền, hãy xem trang hỗ trợ G Suite.

Ví dụ

C#

/*
 * Copyright 2015 Google Inc
 *
 * Licensed under the Apache License, Version 2.0(the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

using Google.Apis.Auth.OAuth2;
using Google.Apis.Dfareporting.v4;
using Google.Apis.Dfareporting.v4.Data;
using Google.Apis.Json;
using Google.Apis.Services;
using System;
using System.Collections.Generic;
using System.IO;

namespace DfaReporting.Samples {
  /// <summary>
  /// This example demonstrates how to authenticate and make a basic request using a service
  /// account.
  /// </summary>
  class AuthenticateUsingServiceAccount : SampleBase {
    /// <summary>
    /// The OAuth 2.0 scopes to request.
    /// </summary>
    private static readonly IEnumerable<string> OAuthScopes = new[] {
      DfareportingService.Scope.Dfareporting
    };

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This example demonstrates how to authenticate and make a basic request" +
               " using a service account.\n";
      }
    }

    /// <summary>
    /// Main method, to run this code example as a standalone application.
    /// </summary>
    /// <param name="args">The command line arguments.</param>
    public static void Main(string[] args) {
      SampleBase codeExample = new AuthenticateUsingServiceAccount();
      Console.WriteLine(codeExample.Description);
      codeExample.Run(null);
    }

    /// <summary>
    /// Run the code example.
    /// </summary>
    /// <param name="service">Unused</param>
    public override void Run(DfareportingService service) {
      string pathToJsonFile = _T("ENTER_PATH_TO_JSON_FILE_HERE");

      // An optional Google account email to impersonate. Only applicable to service accounts which
      // have enabled domain-wide delegation and wish to make API requests on behalf of an account
      // within their domain. Setting this field will not allow you to impersonate a user from a
      // domain you don't own (e.g., gmail.com).
      string emailToImpersonate = _T("");

      // Build service account credential.
      ServiceAccountCredential credential =
          getServiceAccountCredential(pathToJsonFile, emailToImpersonate);

      // Create a Dfareporting service object.
      //
      // Note: application name should be replaced with a value that identifies your application.
      service = new DfareportingService(
          new BaseClientService.Initializer {
            HttpClientInitializer = credential,
            ApplicationName = "C# service account sample"
          }
      );

      // Retrieve and print all user profiles for the current authorized user.
      UserProfileList profiles = service.UserProfiles.List().Execute();

      foreach (UserProfile profile in profiles.Items) {
        Console.WriteLine("Found user profile with ID {0} and name \"{1}\".",
            profile.ProfileId, profile.UserName);
      }
    }

    private ServiceAccountCredential getServiceAccountCredential(String pathToJsonFile,
        String emailToImpersonate) {
      // Load and deserialize credential parameters from the specified JSON file.
      JsonCredentialParameters parameters;
      using (Stream json = new FileStream(pathToJsonFile, FileMode.Open, FileAccess.Read)) {
        parameters = NewtonsoftJsonSerializer.Instance.Deserialize<JsonCredentialParameters>(json);
      }

      // Create a credential initializer with the correct scopes.
      ServiceAccountCredential.Initializer initializer =
          new ServiceAccountCredential.Initializer(parameters.ClientEmail) {
            Scopes = OAuthScopes
          };

      // Configure impersonation (if applicable).
      if (!String.IsNullOrEmpty(emailToImpersonate)) {
        initializer.User = emailToImpersonate;
      }

      // Create a service account credential object using the deserialized private key.
      ServiceAccountCredential credential =
          new ServiceAccountCredential(initializer.FromPrivateKey(parameters.PrivateKey));

      return credential;
    }
  }
}

Java

// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.api.services.samples.dfareporting.auth;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.dfareporting.Dfareporting;
import com.google.api.services.dfareporting.DfareportingScopes;
import com.google.api.services.dfareporting.model.UserProfileList;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import java.io.FileInputStream;

/**
 * This example demonstrates how to authenticate and make a basic request using a service account.
 */
public class AuthenticateUsingServiceAccount {
  private static final String PATH_TO_JSON_FILE = "ENTER_PATH_TO_JSON_FILE_HERE";

  /**
   * An optional Google account email to impersonate. Only applicable to service accounts which have
   * enabled domain-wide delegation and wish to make API requests on behalf of an account within
   * their domain. Setting this field will not allow you to impersonate a user from a domain you
   * don't own (e.g., gmail.com).
   */
  private static final String EMAIL_TO_IMPERSONATE = "";

  // The OAuth 2.0 scopes to request.
  private static final ImmutableSet<String> OAUTH_SCOPES =
      ImmutableSet.of(DfareportingScopes.DFAREPORTING);

  private static Credential getServiceAccountCredential(
      String pathToJsonFile, String emailToImpersonate) throws Exception {
    // Generate a credential object from the specified JSON file.
    GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(pathToJsonFile));

    // Update the credential object with appropriate scopes and impersonation info (if applicable).
    if (Strings.isNullOrEmpty(emailToImpersonate)) {
      credential = credential.createScoped(OAUTH_SCOPES);
    } else {
      credential =
          new GoogleCredential.Builder()
              .setTransport(credential.getTransport())
              .setJsonFactory(credential.getJsonFactory())
              .setServiceAccountId(credential.getServiceAccountId())
              .setServiceAccountPrivateKey(credential.getServiceAccountPrivateKey())
              .setServiceAccountScopes(OAUTH_SCOPES)
              // Set the email of the user you are impersonating (this can be yourself).
              .setServiceAccountUser(emailToImpersonate)
              .build();
    }

    return credential;
  }

  public static void runExample(Dfareporting reporting) throws Exception {
    // Retrieve and print all user profiles for the current authorized user.
    UserProfileList profiles = reporting.userProfiles().list().execute();
    for (int i = 0; i < profiles.getItems().size(); i++) {
      System.out.printf("%d) %s%n", i + 1, profiles.getItems().get(i).getUserName());
    }
  }

  public static void main(String[] args) throws Exception {
    // Build service account credential.
    Credential credential = getServiceAccountCredential(PATH_TO_JSON_FILE, EMAIL_TO_IMPERSONATE);

    // Create a Dfareporting client instance.
    //
    // Note: application name below should be replaced with a value that identifies your
    // application. Suggested format is "MyCompany-ProductName/Version.MinorVersion".
    Dfareporting reporting =
        new Dfareporting.Builder(credential.getTransport(), credential.getJsonFactory(), credential)
            .setApplicationName("dfareporting-java-service-acct-sample")
            .build();

    runExample(reporting);
  }
}

PHP

<?php
/*
 * Copyright 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

require_once dirname(__DIR__) . '/vendor/autoload.php';

/**
 * This example demonstrates how to authenticate and make a basic request using
 * a service account.
 *
 * This example is written to be run as a command line application, not as a
 * webpage. An optional Google account email to impersonate may be specified as
 * follows:
 *
 *     AuthenticateUsingServiceAccount.php /path/to/client_secrets.json <email>
 *
 * This optional flag only applies to service accounts which have domain-wide
 * delegation enabled and wish to make API requests on behalf of an account
 * within that domain. Using this flag will not allow you to impersonate a user
 * from a domain that you don't own (e.g., gmail.com).
 */
class AuthenticateUsingServiceAccount
{
    // The OAuth 2.0 scopes to request.
    private static $OAUTH_SCOPES = [
        Google_Service_Dfareporting::DFAREPORTING
    ];

    public function run($pathToJsonFile, $email = null)
    {
        // Create an authenticated client object.
        $client = $this->createAuthenticatedClient($pathToJsonFile, $email);

        // Create a Dfareporting service object.
        $service = new Google_Service_Dfareporting($client);

        $this->getUserProfiles($service);
    }

    private function createAuthenticatedClient($pathToJsonFile, $email)
    {
        // Create a Google_Client instance.
        //
        // Note: application name should be replaced with a value that identifies
        // your application. Suggested format is "MyCompany-ProductName".
        $client = new Google_Client();
        $client->setApplicationName('PHP service account sample');
        $client->setScopes(self::$OAUTH_SCOPES);

        // Load the service account credentials.
        $client->setAuthConfig($pathToJsonFile);

        // Configure impersonation (if applicable).
        if (!is_null($email)) {
            $client->setSubject($email);
        }

        return $client;
    }

    private function getUserProfiles($service)
    {
        // Retrieve and print all user profiles for the current authorized user.
        $result = $service->userProfiles->listUserProfiles();
        foreach ($result['items'] as $userProfile) {
            printf(
                "User profile \"%s\" (ID: %d) found for account %d.\n",
                $userProfile->getUserName(),
                $userProfile->getProfileId(),
                $userProfile->getAccountId()
            );
        }
    }
}

if ($argc < 2 || $argc >= 4) {
    printf(
        "Usage: %s /path/to/client_secrets.json [email_to_impersonate]\n",
        $argv[0]
    );
} else {
    $sample = new AuthenticateUsingServiceAccount();

    if ($argc == 2) {
        $sample->run($argv[1]);
    } else {
        $sample->run($argv[1], $argv[2]);
    }
}

Python

#!/usr/bin/python
#
# Copyright 2015 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""This example demonstrates how to authenticate using a service account.

An optional Google account email to impersonate may be specified as follows:
    authenticate_using_service_account.py <path_to_json_file> -i <email>

This optional flag only applies to service accounts which have domain-wide
delegation enabled and wish to make API requests on behalf of an account
within that domain. Using this flag will not allow you to impersonate a
user from a domain you don't own (e.g., gmail.com).
"""

import argparse
import sys

from googleapiclient import discovery
import httplib2
from oauth2client import client
from oauth2client import tools
from oauth2client.service_account import ServiceAccountCredentials

# Declare command-line flags.
argparser = argparse.ArgumentParser(add_help=False)
argparser.add_argument(
    'path_to_service_account_json_file',
    help='Path to the service account JSON file to use for authenticating.')
argparser.add_argument(
    '-i',
    '--impersonation_email',
    help='Google account email to impersonate.')

# The OAuth 2.0 scopes to request.
OAUTH_SCOPES = ['https://www.googleapis.com/auth/dfareporting']


def main(argv):
  # Retrieve command line arguments.
  parser = argparse.ArgumentParser(
      description=__doc__,
      formatter_class=argparse.RawDescriptionHelpFormatter,
      parents=[tools.argparser, argparser])
  flags = parser.parse_args(argv[1:])

  # Authenticate using the supplied service account credentials
  http = authenticate_using_service_account(
      flags.path_to_service_account_json_file,
      flags.impersonation_email)

  # Construct a service object via the discovery service.
  service = discovery.build('dfareporting', 'v4', http=http)

  try:
    # Construct the request.
    request = service.userProfiles().list()

    # Execute request and print response.
    response = request.execute()

    for profile in response['items']:
      print('Found user profile with ID %s and user name "%s".' %
            (profile['profileId'], profile['userName']))

  except client.AccessTokenRefreshError:
    print('The credentials have been revoked or expired, please re-run the '
          'application to re-authorize')


def authenticate_using_service_account(path_to_service_account_json_file,
                                       impersonation_email):
  """Authorizes an httplib2.Http instance using service account credentials."""
  # Load the service account credentials from the specified JSON keyfile.
  credentials = ServiceAccountCredentials.from_json_keyfile_name(
      path_to_service_account_json_file,
      scopes=OAUTH_SCOPES)

  # Configure impersonation (if applicable).
  if impersonation_email:
    credentials = credentials.create_delegated(impersonation_email)

  # Use the credentials to authorize an httplib2.Http instance.
  http = credentials.authorize(httplib2.Http())

  return http


if __name__ == '__main__':
  main(sys.argv)

Ruby

#!/usr/bin/env ruby

#
# Copyright:: Copyright 2016, Google Inc. All Rights Reserved.
#
# License:: Licensed under the Apache License, Version 2.0 (the "License");
#           you may not use this file except in compliance with the License.
#           You may obtain a copy of the License at
#
#           http://www.apache.org/licenses/LICENSE-2.0
#
#           Unless required by applicable law or agreed to in writing, software
#           distributed under the License is distributed on an "AS IS" BASIS,
#           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
#           implied.
#           See the License for the specific language governing permissions and
#           limitations under the License.
#
# This example demonstrates how to authenticate using a service account.
#
# An optional Google account email to impersonate may be specified as follows:
#    authenticate_using_service_account.rb <path_to_json_file> --i <email>
#
# This optional flag only applies to service accounts which have domain-wide
# delegation enabled and wish to make API requests on behalf of an account
# within that domain. Using this flag will not allow you to impersonate a
# user from a domain you don't own (e.g., gmail.com).

require 'google/apis/dfareporting_v4'
require 'googleauth'
require 'optparse'

API_NAMESPACE = Google::Apis::DfareportingV4

def authenticate_using_service_account(path_to_json_file, impersonation_email)
  # Create a Dfareporting service object.
  #
  # Note: application name should be replaced with a value that identifies
  # your application. Suggested format is "MyCompany-ProductName".
  service = API_NAMESPACE::DfareportingService.new
  service.client_options.application_name = 'Ruby service account sample'
  service.client_options.application_version = '1.0.0'

  # Generate an authorization object from the specified JSON file.
  File.open(path_to_json_file, 'r+') do |json|
    service.authorization =
      Google::Auth::ServiceAccountCredentials.make_creds(
        json_key_io: json,
        scope: [API_NAMESPACE::AUTH_DFAREPORTING]
      )
  end

  # Configure impersonation (if applicable).
  service.authorization.sub = impersonation_email unless
    impersonation_email.nil?

  service
end

def get_userprofiles(service)
  # Get all user profiles.
  result = service.list_user_profiles

  # Display results.
  result.items.each do |profile|
    puts format(
      'User profile with ID %d and name "%s" was found for account %d.',
      profile.profile_id, profile.user_name, profile.account_id
    )
  end
end

if $PROGRAM_NAME == __FILE__
  # Retrieve command line arguments.
  impersonation_email = nil
  optparse = OptionParser.new do |opts|
    opts.banner = format('Usage: %s path_to_json_file [options]', $PROGRAM_NAME)
    opts.on_tail('-i', '--impersonate EMAIL',
      'Google account email to impersonate') do |email|
      impersonation_email = email
    end
  end
  optparse.parse!

  if ARGV.empty?
    puts optparse
    exit(-1)
  end

  # Authenticate and initialize API service using service account.
  service = authenticate_using_service_account(ARGV.shift, impersonation_email)

  get_userprofiles(service)
end