אימות כחשבונות שירות

כאן מוסבר איך מבצעים אימות באפליקציה כחשבון שירות. למידע כללי על אימות ב-Google Cloud APIs, כולל אסטרטגיות ותרחישי אימות נפוצים, תוכלו לקרוא את הסקירה הכללית בקשר לאימות. למידע נוסף על חשבונות שירות, תוכלו לקרוא את המאמר חשבונות שירות במרכז העזרה של 'ניהול זהויות והרשאות גישה'.

חיפוש אוטומטי של פרטי הכניסה

אם האפליקציה פועלת בסביבת Google Cloud וחיברתם חשבון שירות לאותה סביבה, האפליקציה יכולה לאחזר את פרטי הכניסה לחשבון השירות ולהשתמש בהם כדי להתחבר ל-Google Cloud APIs.

אתם יכולים לחבר חשבונות שירות למשאבים בשירותים רבים ושונים של Google Cloud, כולל Compute Engine, ‏Google Kubernetes Engine, ‏App Engine, ‏Cloud Run ו-Cloud Functions. מומלץ להשתמש באסטרטגיה הזו כי היא נוחה ומאובטחת יותר מאשר העברה ידנית של פרטי הכניסה.

בנוסף, מומלץ לשלוח את הבקשה באמצעות ספריות הלקוח של Google Cloud. ספריות הלקוח של Google Cloud כוללות ספרייה בשם Application Default Credentials‏ (ADC), שמאפשרת לחפש אוטומטית את פרטי הכניסה. החיפוש של פרטי הכניסה לחשבון השירות ב-ADC מתבצע בסדר הבא:

  1. אם משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS מוגדר, חיפוש פרטי הכניסה ב-ADC מתבצע באמצעות המַפְתח לחשבון השירות או קובץ התצורה שהמשתנה מצביע אליו.

  2. אם משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS לא מוגדר, חיפוש פרטי הכניסה ב-ADC מתבצע באמצעות חשבון השירות שמחובר למשאב שמפעיל את הקוד.

    חשבון השירות הזה יכול להיות חשבון ברירת המחדל שמסופק על ידי Compute Engine, ‏Google Kubernetes Engine, ‏App Engine, ‏Cloud Run או Cloud Functions. הוא גם יכול להיות חשבון שירות שמנוהל על ידי משתמש שאתם יצרתם.

  3. אם המערכת של ADC לא מצליחה להשתמש בפרטי הכניסה האלו, מופיעה הודעת שגיאה.

תוכלו להיעזר בדוגמת הקוד הבאה כדי להבין איך להשתמש בספריית ADC בקוד האפליקציה. כדי להריץ את הדוגמה הזו, צריך להתקין את ספריית הלקוח Cloud Storage.

C#‎

public object AuthImplicit(string projectId)
{
    // If you don't specify credentials when constructing the client, the
    // client library will look for credentials in the environment.
    var credential = GoogleCredential.GetApplicationDefault();
    var storage = StorageClient.Create(credential);
    // Make an authenticated API request.
    var buckets = storage.ListBuckets(projectId);
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name);
    }
    return null;
}

Go


// implicit uses Application Default Credentials to authenticate.
func implicit() {
	ctx := context.Background()

	// For API packages whose import path is starting with "cloud.google.com/go",
	// such as cloud.google.com/go/storage in this case, if there are no credentials
	// provided, the client library will look for credentials in the environment.
	storageClient, err := storage.NewClient(ctx)
	if err != nil {
		log.Fatal(err)
	}
	defer storageClient.Close()

	it := storageClient.Buckets(ctx, "project-id")
	for {
		bucketAttrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(bucketAttrs.Name)
	}

	// For packages whose import path is starting with "google.golang.org/api",
	// such as google.golang.org/api/cloudkms/v1, use NewService to create the client.
	kmsService, err := cloudkms.NewService(ctx)
	if err != nil {
		log.Fatal(err)
	}

	_ = kmsService
}

Java

static void authImplicit() {
  // If you don't specify credentials when constructing the client, the client library will
  // look for credentials via the environment variable GOOGLE_APPLICATION_CREDENTIALS.
  Storage storage = StorageOptions.getDefaultInstance().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

Node.js

// Imports the Google Cloud client library.
const {Storage} = require('@google-cloud/storage');

// Instantiates a client. If you don't specify credentials when constructing
// the client, the client library will look for credentials in the
// environment.
const storage = new Storage();
// Makes an authenticated API request.
async function listBuckets() {
  try {
    const results = await storage.getBuckets();

    const [buckets] = results;

    console.log('Buckets:');
    buckets.forEach(bucket => {
      console.log(bucket.name);
    });
  } catch (err) {
    console.error('ERROR:', err);
  }
}
listBuckets();

PHP

// Imports the Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

/**
 * Authenticate to a cloud client library using a service account implicitly.
 *
 * @param string $projectId The Google project ID.
 */
function auth_cloud_implicit($projectId)
{
    $config = [
        'projectId' => $projectId,
    ];

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def implicit():
    from google.cloud import storage

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    storage_client = storage.Client()

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

# project_id = "Your Google Cloud project ID"

require "google/cloud/storage"

# If you don't specify credentials when constructing the client, the client
# library will look for credentials in the environment.
storage = Google::Cloud::Storage.new project: project_id

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

העברה ידנית של פרטי הכניסה

אם האפליקציה פועלת בסביבה שלא חובר אליה אף חשבון שירות, כמו מערכת מקומית בארגון או ספק אחר של שירותי ענן, כדאי להשתמש בשירות המשולב לזיהוי עומסי עבודה.

אם אתם לא יכולים להשתמש בשירות המשולב לזיהוי עומסי עבודה, תצטרכו ליצור חשבון שירות ולפחות מַפְתח אחד לחשבון השירות, כלומר פרטי כניסה המשויכים לחשבון השירות. כך תוכלו להעביר ידנית לאפליקציה את המפתחות לחשבונות השירות.

מומלץ לקרוא את השיטות המומלצות לניהול מפתחות לחשבונות שירות.

יצירת חשבון שירות

אם אין לכם חשבון שירות, תוכלו להיעזר בהוראות הבאות כדי ליצור אחד:

המסוף

יוצרים חשבון שירות:

  1. נכנסים לדף Create service account במסוף Google Cloud.

    כניסה לדף Create service account
  2. בוחרים את הפרויקט הרצוי.
  3. כותבים שם בשדה Service account name. השדה Service account ID במסוף Google Cloud יאוכלס בהתאם לשם הזה.

    כותבים תיאור בשדה Service account description. לדוגמה: Service account for quickstart.

  4. לוחצים על Create and continue.
  5. כדי לתת גישה לפרויקט, נותנים לחשבון השירות את התפקידים הבאים: פרויקט > בעלים.

    בוחרים תפקיד מהרשימה Select a role.

    כדי להוסיף עוד תפקידים, לוחצים על Add another role ומוסיפים אותם אחד אחרי השני.

  6. לוחצים על Continue.
  7. לוחצים על Done כדי לסיים ליצור את חשבון השירות.

    חשוב לא לסגור את חלון הדפדפן, כי תשתמשו בו גם בשלב הבא.

יוצרים מַפְתח לחשבון השירות:

  1. במסוף Google Cloud, לוחצים על כתובת האימייל של חשבון השירות שנוצר.
  2. לוחצים על Keys.
  3. לוחצים על Add key ואז על Create new key.
  4. לוחצים על Create. למחשב שלכם תתבצע הורדה של קובץ JSON עם המַפְתח.
  5. לוחצים על Close.

gcloud

מגדירים את האימות:

  1. יוצרים את חשבון השירות:

    gcloud iam service-accounts create NAME

    מחליפים את הערך NAME בשם שרוצים לתת לחשבון השירות.

  2. נותנים לחשבון השירות תפקידים. מריצים את הפקודה הבאה לכל אחד מהתפקידים הבאים ב-IAM: roles/owner:

    gcloud projects add-iam-policy-binding PROJECT_ID --member="serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com" --role=ROLE

    מחליפים את מה שכתוב בשדות הבאים:

    • SERVICE_ACCOUNT_NAME: השם של חשבון השירות
    • PROJECT_ID: מזהה הפרויקט שבו יצרתם את חשבון השירות
    • ROLE: התפקיד שאתם רוצים לתת
  3. יוצרים את קובץ המַפְתח:

    gcloud iam service-accounts keys create FILE_NAME.json --iam-account=SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

    מחליפים את מה שכתוב בשדות הבאים:

    • FILE_NAME: שם לקובץ המַפְתח
    • SERVICE_ACCOUNT_NAME: השם של חשבון השירות
    • PROJECT_ID: מזהה הפרויקט שבו יצרתם את חשבון השירות

העברת פרטי הכניסה באמצעות משתנה סביבה

מגדירים את משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS כדי לספק את פרטי הכניסה לקוד האפליקציה. המשתנה הזה חל רק על סשן המעטפת הנוכחי. אם רוצים שהמשתנה יחול על סשנים נוספים של המעטפת, מגדירים את המשתנה בקובץ ההפעלה של המעטפת – למשל בקובץ ~/.bashrc או בקובץ ~/.profile.

Linux או macOS

export GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH"

מחליפים את KEY_PATH בנתיב של קובץ ה-JSON שמכיל את המַפְתח של חשבון השירות.

למשל:

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

Windows

ל-PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH"

מחליפים את KEY_PATH בנתיב של קובץ ה-JSON שמכיל את המַפְתח של חשבון השירות.

למשל:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

בשורת הפקודה:

set GOOGLE_APPLICATION_CREDENTIALS=KEY_PATH

מחליפים את KEY_PATH בנתיב של קובץ ה-JSON שמכיל את המַפְתח של חשבון השירות.

אחרי ביצוע הפעולות שלמעלה, תוכלו לחפש אוטומטית את פרטי הכניסה ב-ADC כמו שהסברנו כאן. מומלץ להשתמש ב-ADC כי הוא מצריך פחות קוד ואפשר להעביר את הקוד לסביבות שונות.

העברת פרטי הכניסה באמצעות קוד

אתם יכולים גם להצביע ישירות על הקובץ של חשבון השירות בקוד, כמו בדוגמה הבאה. כדי להריץ את הדוגמה הזו צריך להתקין את ספריית הלקוח Cloud Storage.

C#‎

        // Some APIs, like Storage, accept a credential in their Create()
        // method.
        public object AuthExplicit(string projectId, string jsonPath)
        {
            // Explicitly use service account credentials by specifying
            // the private key file.
            var credential = GoogleCredential.FromFile(jsonPath);
            var storage = StorageClient.Create(credential);
            // Make an authenticated API request.
            var buckets = storage.ListBuckets(projectId);
            foreach (var bucket in buckets)
            {
                Console.WriteLine(bucket.Name);
            }
            return null;
        }
        // Other APIs, like Language, accept a channel in their Create()
        // method.
        public object AuthExplicit(string projectId, string jsonPath)
        {
            LanguageServiceClientBuilder builder = new LanguageServiceClientBuilder
            {
                CredentialsPath = jsonPath
            };

            LanguageServiceClient client = builder.Build();
            AnalyzeSentiment(client);
            return 0;
        }

Go


// explicit reads credentials from the specified path.
func explicit(jsonPath, projectID string) {
	ctx := context.Background()
	client, err := storage.NewClient(ctx, option.WithCredentialsFile(jsonPath))
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()
	fmt.Println("Buckets:")
	it := client.Buckets(ctx, projectID)
	for {
		battrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(battrs.Name)
	}
}

Java

static void authExplicit(String jsonPath) throws IOException {
  // You can specify a credential file by providing a path to GoogleCredentials.
  // Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
  GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
        .createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
  Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

Node.js

// Imports the Google Cloud client library.
const {Storage} = require('@google-cloud/storage');

// Instantiates a client. Explicitly use service account credentials by
// specifying the private key file. All clients in google-cloud-node have this
// helper, see https://github.com/GoogleCloudPlatform/google-cloud-node/blob/master/docs/authentication.md
// const projectId = 'project-id'
// const keyFilename = '/path/to/keyfile.json'
const storage = new Storage({projectId, keyFilename});

// Makes an authenticated API request.
async function listBuckets() {
  try {
    const [buckets] = await storage.getBuckets();

    console.log('Buckets:');
    buckets.forEach(bucket => {
      console.log(bucket.name);
    });
  } catch (err) {
    console.error('ERROR:', err);
  }
}
listBuckets();

PHP

namespace Google\Cloud\Samples\Auth;

// Imports the Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

/**
 * Authenticate to a cloud client library using a service account explicitly.
 *
 * @param string $projectId           The Google project ID.
 * @param string $serviceAccountPath  Path to service account credentials JSON.
 */
function auth_cloud_explicit($projectId, $serviceAccountPath)
{
    # Explicitly use service account credentials by specifying the private key
    # file.
    $config = [
        'keyFilePath' => $serviceAccountPath,
        'projectId' => $projectId,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def explicit():
    from google.cloud import storage

    # Explicitly use service account credentials by specifying the private key
    # file.
    storage_client = storage.Client.from_service_account_json(
        'service_account.json')

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

# project_id = "Your Google Cloud project ID"
# key_file   = "path/to/service-account.json"
require "google/cloud/storage"

# Explicitly use service account credentials by specifying the private key
# file.
storage = Google::Cloud::Storage.new project: project_id, keyfile: key_file

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

פתרון בעיות הקשורות לשגיאות API

ברשימת הודעות השגיאה של Cloud APIs מוסבר בהרחבה איך פותרים בעיות הקשורות לבקשות API.

המאמרים הבאים

נסו בעצמכם

אנחנו ממליצים למשתמשים חדשים ב-Google Cloud ליצור חשבון כדי שיוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.

מתחילים לעבוד בלי לשלם