Using OAuth 2.0 for Server to Server Applications (Sunucudan Sunucuya Uygulamalar için OAuth 2.0'ı Kullanma)

Google OAuth 2.0 sistemi, web uygulaması ile Google hizmeti arasındaki gibi sunucudan sunucuya etkileşimleri destekler. Bu senaryo için bir hizmet hesabına ihtiyacınız vardır. Bu hesap, bireysel bir son kullanıcı yerine uygulamanıza ait bir hesaptır. Uygulamanız, hizmet hesabı adına Google API'lerini çağırır. Dolayısıyla kullanıcılar bu işleme doğrudan dahil olmaz. Bu senaryoya bazen "iki ayaklı OAuth" veya "2LO" denir. ("Üç aşamalı OAuth" ile ilgili terim, uygulamanızın son kullanıcılar adına Google API'lerini çağırdığı ve bazen kullanıcı izninin gerekli olduğu senaryoları ifade eder.)

Uygulamalar genellikle kullanıcı verilerinden ziyade kendi verileriyle çalışmak için Google API'lerini kullandığında hizmet hesabı kullanır. Örneğin, veri kalıcılığı için Google Cloud Datastore kullanan bir uygulama, Google Cloud Datastore API'ye yaptığı çağrıların kimliğini doğrulamak için bir hizmet hesabı kullanır.

Google Workspace alan yöneticileri, alandaki kullanıcılar adına kullanıcı verilerine erişmek için hizmet hesaplarına alan genelinde yetki verebilir.

Bu dokümanda, bir uygulamanın Google API'leri istemci kitaplığını (önerilen) veya HTTP'yi kullanarak sunucudan sunucuya OAuth 2.0 akışını nasıl tamamlayabileceği açıklanmaktadır.

Genel Bakış

Sunucular arası etkileşimleri desteklemek için öncelikle API Console'te projeniz için bir hizmet hesabı oluşturun. Google Workspace hesabınızdaki kullanıcıların kullanıcı verilerine erişmek istiyorsanız hizmet hesabına alan adı genelinde yetki verin.

Ardından uygulamanız, OAuth 2.0 kimlik doğrulama sunucusundan erişim jetonu istemek için hizmet hesabının kimlik bilgilerini kullanarak yetkili API çağrıları yapmaya hazırlanır.

Son olarak, uygulamanız Google API'lerini çağırmak için erişim jetonunu kullanabilir.

Hizmet hesabı oluşturma

Hizmet hesabının kimlik bilgileri, benzersiz bir şekilde oluşturulmuş bir e-posta adresi ve en az bir herkese açık/özel anahtar çifti içerir. Alan genelinde yetkilendirme etkinse istemci kimliği de hizmet hesabının kimlik bilgilerinin bir parçasıdır.

Uygulamanız Google App Engine'da çalışıyorsa projenizi oluşturduğunuzda otomatik olarak bir hizmet hesabı oluşturulur.

Uygulamanız Google Compute Engine'da çalışıyorsa projenizi oluşturduğunuzda otomatik olarak bir hizmet hesabı da oluşturulur ancak Google Compute Engine örneği oluşturduğunuzda uygulamanızın erişmesi gereken kapsamları belirtmeniz gerekir. Daha fazla bilgi için Bir örneği hizmet hesaplarını kullanacak şekilde hazırlama başlıklı makaleyi inceleyin.

Uygulamanız Google App Engine veya Google Compute Engine'da çalışmıyorsa bu kimlik bilgilerini Google API Console'te edinmeniz gerekir. Hizmet hesabı kimlik bilgileri oluşturmak veya daha önce oluşturduğunuz herkese açık kimlik bilgilerini görüntülemek için şunları yapın:

First, create a service account:

  1. Open the Service accounts page.
  2. If prompted, select a project, or create a new one.
  3. Click  Create service account.
  4. Under Service account details, type a name, ID, and description for the service account, then click Create and continue.
  5. Optional: Under Grant this service account access to project, select the IAM roles to grant to the service account.
  6. Click Continue.
  7. Optional: Under Grant users access to this service account, add the users or groups that are allowed to use and manage the service account.
  8. Click Done.

Next, create a service account key:

  1. Click the email address for the service account you created.
  2. Click the Keys tab.
  3. In the Add key drop-down list, select Create new key.
  4. Click Create.

Your new public/private key pair is generated and downloaded to your machine; it serves as the only copy of the private key. You are responsible for storing it securely. If you lose this key pair, you will need to generate a new one.

E-posta adresini, ortak anahtar parmak izlerini ve diğer bilgileri görüntülemek veya ek ortak/özel anahtar çiftleri oluşturmak için dilediğiniz zaman API Console bölümüne dönebilirsiniz. API Console'teki hizmet hesabı kimlik bilgileri hakkında daha fazla bilgi için API Consoleyardım dosyasında Hizmet hesapları bölümüne bakın.

Hizmet hesabının e-posta adresini not edin ve hizmet hesabının özel anahtar dosyasını uygulamanızın erişebileceği bir konumda depolayın. Uygulamanızın, yetkili API çağrıları yapabilmesi için bu kimlik bilgilerine ihtiyacı vardır.

Hizmet hesabına alan genelinde yetki verme

Kuruluşun bir Workspace yöneticisi, Google Workspace hesabını kullanarak bir uygulamaya Google Workspace alanındaki kullanıcılar adına Workspace kullanıcı verilerine erişme yetkisi verebilir. Örneğin, Google Workspace alanındaki tüm kullanıcıların takvimlerine etkinlik eklemek için Google Takvim API'yi kullanan bir uygulama, kullanıcılar adına Google Takvim API'ye erişmek için bir hizmet hesabı kullanır. Bir hizmet hesabını, alandaki kullanıcılar adına verilere erişmesi için yetkilendirme işlemine bazen hizmet hesabına "alan genelinde yetki verme" denir.

Bir hizmet hesabına alan genelinde yetki vermek için Google Workspace alanının süper yöneticisinin aşağıdaki adımları tamamlaması gerekir:

  1. Google Workspace alanınızın Yönetici Konsolu'nda Ana menü > Güvenlik > Erişim ve veri denetimi > API Denetimleri'ne gidin.
  2. Alan genelinde yetki bölmesinde Alan Genelinde Yetkiyi Yönet'i seçin.
  3. Yeni ekle'yi tıklayın.
  4. İstemci Kimliği alanına hizmet hesabının İstemci Kimliği'ni girin. Hizmet hesabınızın istemci kimliğini Service accounts page'te bulabilirsiniz.
  5. OAuth kapsamları (virgülle ayrılmış) alanına, uygulamanızın erişmesine izin verilmesi gereken kapsamların listesini girin. Örneğin, uygulamanızın Google Drive API'sine ve Google Calendar API'sine alan genelinde tam erişmesi gerekiyorsa şunu girin: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
  6. Yetkilendir'i tıklayın.

Uygulamanız artık Workspace alanınızdaki kullanıcılar olarak API çağrıları yapma yetkisine (kullanıcıları "taklit etmek" için) sahiptir. Bu yetki verilmiş API çağrılarını yapmaya hazırlanırken kimliğine bürüneceğiniz kullanıcıyı açıkça belirtirsiniz.

Yetki verilmiş bir API çağrısı yapmaya hazırlanma

Java

API Console'ten istemci e-posta adresini ve özel anahtarı aldıktan sonra, hizmet hesabının kimlik bilgilerinden ve uygulamanızın erişmesi gereken kapsamlardan GoogleCredential nesnesi oluşturmak için Java için Google API'leri istemci kitaplığını kullanın. Örneğin:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

Google Cloud Platform'da uygulama geliştiriyorsanız bunun yerine uygulama varsayılan kimlik bilgilerini kullanabilirsiniz. Bu, süreci basitleştirebilir.

Alan genelinde yetki verme

Hizmet hesabına alan genelinde erişim yetkisi verdiyseniz ve bir kullanıcı hesabının kimliğine bürünmek istiyorsanız GoogleCredential nesnesinin createDelegated yöntemini kullanarak kullanıcı hesabının e-posta adresini belirtin. Örneğin:

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("workspace-user@example.com");

Yukarıdaki kod, createDelegated() yöntemini çağırmak için GoogleCredential nesnesini kullanır. createDelegated() yönteminin bağımsız değişkeni, Workspace hesabınıza ait bir kullanıcı olmalıdır. İsteği gönderen kodunuz, hizmet hesabınızı kullanarak Google API'lerini çağırmak için bu kimlik bilgisini kullanır.

Python

API Console'den istemci e-posta adresini ve özel anahtarı aldıktan sonra, aşağıdaki adımları tamamlamak için Python için Google API'leri İstemci Kitaplığı'nı kullanın:

  1. Hizmet hesabının kimlik bilgilerinden ve uygulamanızın erişmesi gereken kapsamlardan bir Credentials nesnesi oluşturun. Örneğin:
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    Google Cloud Platform'da uygulama geliştiriyorsanız bunun yerine uygulama varsayılan kimlik bilgilerini kullanabilirsiniz. Bu, süreci basitleştirebilir.

  2. Alan genelinde yetki verme

    Hizmet hesabına alan genelinde erişim yetkisi verdiyseniz ve bir kullanıcı hesabının kimliğine bürünmek istiyorsanız mevcut bir ServiceAccountCredentials nesnesinin with_subject yöntemini kullanın. Örneğin:

    delegated_credentials = credentials.with_subject('user@example.org')

Uygulamanızda Google API'lerini çağırmak için Kimlik Bilgileri nesnesini kullanın.

HTTP/REST

API Console'den istemci kimliğini ve özel anahtarı aldıktan sonra, uygulamanızın aşağıdaki adımları tamamlaması gerekir:

  1. Başlık, iddia kümesi ve imza içeren bir JSON Web Jetonu ("jot" olarak okunur) oluşturun.
  2. Google OAuth 2.0 Yetkilendirme Sunucusu'ndan erişim jetonu isteyin.
  3. Yetkilendirme sunucusunun döndürdüğü JSON yanıtını işleyin.

Aşağıdaki bölümlerde bu adımların nasıl tamamlanacağı açıklanmaktadır.

Yanıt bir erişim jetonu içeriyorsa bir Google API'sini çağırmak için erişim jetonunu kullanabilirsiniz. (Yanıt erişim jetonu içermiyorsa JWT ve jeton isteğiniz düzgün oluşturulmamış olabilir veya hizmet hesabının istenen kapsamlara erişme izni olmayabilir.)

Erişim jetonunun süresi dolduğunda uygulamanız başka bir JWT oluşturur, imzalar ve başka bir erişim jetonu ister.

Sunucu uygulamanız, Google Yetkilendirme Sunucusu'ndan jeton istemek için JWT kullanır, ardından jetonu bir Google API uç noktasını çağırmak için kullanır. Son kullanıcılar bu işleme dahil değildir.

Bu bölümün geri kalanında, JWT oluşturma, JWT'yi imzalama, erişim jetonu isteğini oluşturma ve yanıtı işleme ile ilgili ayrıntılar açıklanmaktadır.

JWT oluşturma

JWT üç bölümden oluşur: başlık, iddia grubu ve imza. Başlık ve hak talebi grubu JSON nesneleridir. Bu JSON nesneleri UTF-8 baytlarına serileştirilir ve ardından Base64url kodlaması kullanılarak kodlanır. Bu kodlama, tekrarlanan kodlama işlemlerinden kaynaklanan kodlama değişikliklerine karşı direnç sağlar. Başlık, hak talebi grubu ve imza, nokta (.) karakteriyle birlikte birleştirilir.

JWT aşağıdaki şekilde oluşturulur:

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

İmzanın temel dizesi aşağıdaki gibidir:

{Base64url encoded header}.{Base64url encoded claim set}
JWT üst bilgisini oluşturma

Başlık, imzalama algoritmasını, beyanın biçimini ve JWT'yi imzalamak için kullanılan [hizmet hesabı anahtarının anahtar kimliğini](https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys) belirten üç alandan oluşur. Algoritma ve biçim zorunludur ve her alanın yalnızca bir değeri vardır. Ek algoritmalar ve biçimler kullanıma sunulduğunda bu başlık buna göre değişir. Anahtar kimliği isteğe bağlıdır ve yanlış bir anahtar kimliği belirtilirse GCP, jetonu doğrulamak için hizmet hesabıyla ilişkili tüm anahtarları dener ve geçerli bir anahtar bulunamazsa jetonu reddeder. Google, gelecekte yanlış anahtar kimliklerine sahip jetonları reddetme hakkını saklı tutar.

Hizmet hesapları, RSA SHA-256 algoritmasını ve JWT jeton biçimini kullanır. Sonuç olarak, başlığın JSON gösterimi şu şekildedir:

{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}

Bunun Base64url gösterimi şu şekildedir:

          eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
JWT hak talebi kümesini oluşturma

JWT hak talebi grubu, istenen izinler (kapsamlar), jetonun hedefi, ihraç eden, jetonun verildiği zaman ve jetonun geçerlilik süresi dahil olmak üzere JWT hakkında bilgi içerir. Alanların çoğu zorunludur. JWT başlığı gibi, JWT talep kümesi de bir JSON nesnesi olup imzanın hesaplanmasında kullanılır.

Gerekli hak talepleri

JWT hak talebi grubunda gerekli hak talepleri aşağıda gösterilmiştir. Bunlar hak talebi grubunda herhangi bir sırada görünebilir.

Ad Açıklama
iss Hizmet hesabının e-posta adresi.
scope Uygulamanın istediği izinlerin boşlukla ayrılmış listesi.
aud İddianın amaçlanan hedefini tanımlayan bir tanımlayıcı. Erişim jetonu isteği yapılırken bu değer her zaman https://oauth2.googleapis.com/token olur.
exp 1 Ocak 1970, 00:00:00 UTC itibarıyla saniye cinsinden belirtilen iddianın geçerlilik bitiş zamanı. Bu değer, yayınlanma zamanından itibaren en fazla 1 saat geçerlidir.
iat Beyan'ın verildiği zaman (1 Ocak 1970, 00:00:00 UTC'den itibaren saniye cinsinden belirtilir).

JWT talep kümesinde zorunlu alanların JSON gösterimi aşağıda gösterilmiştir:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Ek hak talepleri

Bazı kurumsal durumlarda, bir uygulama bir kuruluştaki belirli bir kullanıcı adına hareket etmek için alan genelinde yetkilendirmeyi kullanabilir. Bu tür kimliğe bürünme işlemini gerçekleştirme izni, bir uygulamanın kullanıcı kimliğine bürünebilmesi için verilmelidir ve genellikle bir süper yönetici tarafından yönetilir. Daha fazla bilgi için Alan genelinde yetkiyle API erişimini kontrol etme başlıklı makaleyi inceleyin.

Bir uygulamaya bir kaynağa yetki verilmiş erişim izni veren bir erişim jetonu almak için kullanıcının e-posta adresini JWT hak talebine sub alanının değeri olarak ekleyin.

Ad Açıklama
sub Uygulamanın yetki verilmiş erişim istediği kullanıcının e-posta adresi.

Bir uygulamanın kullanıcı kimliğine bürünme izni yoksa sub alanını içeren bir erişim jetonu isteğine yanıt olarak hata döndürülür.

Aşağıda, sub alanını içeren bir JWT hak talebi grubu örneği gösterilmektedir:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
JWT hak talebi kümesini kodlama

JWT başlığı gibi JWT hak talebi grubu da UTF-8 olarak serileştirilmeli ve Base64url güvenli kodla kodlanmalıdır. Aşağıda, JWT iddia kümesinin JSON gösterimi örneği verilmiştir:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
İmzayı hesaplama

JSON Web Signature (JWS), JWT için imza oluşturma mekanizmasına yön veren spesifikasyondur. İmzanın girişi, aşağıdaki içeriğin bayt dizisidir:

{Base64url encoded header}.{Base64url encoded claim set}

İmza hesaplanırken JWT başlığındaki imzalama algoritması kullanılmalıdır. Google OAuth 2.0 Yetkilendirme Sunucusu tarafından desteklenen tek imzalama algoritması, SHA-256 karma oluşturma algoritmasını kullanan RSA'dır. Bu değer, JWT üstbilgisinin alg alanında RS256 olarak ifade edilir.

Girişin UTF-8 temsilini, Google API Consolekaynağından elde edilen gizli anahtarla SHA256withRSA (SHA-256 karma oluşturma işleviyle RSASSA-PKCS1-V1_5-SIGN olarak da bilinir) kullanarak imzalayın. Çıkış bir bayt dizisi olur.

İmza daha sonra Base64url kodlamalı olmalıdır. Başlık, hak talebi grubu ve imza, nokta (.) karakteriyle birlikte birleştirilir. Sonuç, JWT olur. Aşağıdaki gibi olmalıdır (anlaşılırlık için satır sonları eklenmiştir):

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

Aşağıda, Base64url kodlamasından önceki bir JWT örneği verilmiştir:

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

Aşağıda, imzalanmış ve iletmeye hazır bir JWT örneği verilmiştir:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

Erişim jetonu isteği yapma

Uygulamalar, imzalanan JWT'yi oluşturduktan sonra erişim jetonu istemek için kullanabilir. Bu erişim jetonu isteği bir HTTPS POST isteğidir ve gövde URL kodlamalıdır. URL aşağıda gösterilmiştir:

https://oauth2.googleapis.com/token

HTTPS POST isteğinde aşağıdaki parametreler gereklidir:

Ad Açıklama
grant_type Gerekirse URL olarak kodlanmış aşağıdaki dizeyi kullanın: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion İmza dahil JWT.

Erişim jetonu isteğinde kullanılan HTTPS POST isteğinin ham dökümü aşağıda verilmiştir:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

Aşağıda, curl kullanılarak yapılan aynı istek gösterilmektedir:

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

Yanıtı ele alma

JWT ve erişim jetonu isteği düzgün bir şekilde oluşturulduysa ve hizmet hesabının işlemi gerçekleştirme izni varsa yetkilendirme sunucusundan gelen JSON yanıtında bir erişim jetonu bulunur. Aşağıda örnek bir yanıt verilmiştir:

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

Erişim jetonları, expires_in değeri tarafından belirtilen süre aralığında yeniden kullanılabilir.

Google API'lerini çağırma

Java

Aşağıdaki adımları uygulayarak Google API'lerini çağırmak için GoogleCredential nesnesini kullanın:

  1. GoogleCredential nesnesini kullanarak çağırmak istediğiniz API için bir hizmet nesnesi oluşturun. Örneğin:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. Hizmet nesnesi tarafından sağlanan arayüzü kullanarak API hizmetine istek gönderin. Örneğin, exciting-example-123 projesindeki Cloud SQL veritabanı örneklerini listelemek için:
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Python

Aşağıdaki adımları uygulayarak Google API'lerini çağırmak için yetkili Credentials nesnesini kullanın:

  1. Çağırmak istediğiniz API için bir hizmet nesnesi oluşturun. API'nin adı ve sürümü ile yetkili Credentials nesnesini kullanarak build işlevini çağırarak bir hizmet nesnesi oluşturursunuz. Örneğin, Cloud SQL Administration API'nin 1beta3 sürümünü çağırmak için:
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
  2. Hizmet nesnesi tarafından sağlanan arayüzü kullanarak API hizmetine istek gönderin. Örneğin, exciting-example-123 projesindeki Cloud SQL veritabanı örneklerini listelemek için:
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP/REST

Uygulamanız erişim jetonu aldıktan sonra, API tarafından istenen erişim kapsamları verilmişse belirli bir hizmet hesabı veya kullanıcı hesabı adına bir Google API'sine çağrı yapmak için jetonu kullanabilirsiniz. Bunu yapmak için access_token sorgu parametresi veya Authorization HTTP üst bilgisi Bearer değeri ekleyerek erişim jetonunu API'ye gönderilen bir isteğe ekleyin. Sorgu dizeleri sunucu günlüklerinde görünmeye eğilimli olduğundan, mümkün olduğunda HTTP üst bilgisi tercih edilir. Çoğu durumda, Google API'lerine yönelik çağrılarınızı ayarlamak için bir istemci kitaplığı kullanabilirsiniz (örneğin, Drive Files API'yi çağırırken).

Tüm Google API'lerini deneyebilir ve kapsamlarını OAuth 2.0 Playground'da görüntüleyebilirsiniz.

HTTP GET örnekleri

Authorization: Bearer HTTP üst bilgisi kullanılarak drive.files uç noktasına (Drive Dosyalar API'si) yapılan bir çağrı aşağıdaki gibi görünebilir. Kendi erişim jetonunuzu belirtmeniz gerektiğini unutmayın:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Kimliği doğrulanmış kullanıcı için access_token sorgu dizesi parametresini kullanan aynı API'ye yapılan bir çağrı aşağıda verilmiştir:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

curl örnek

Bu komutları curl komut satırı uygulamasıyla test edebilirsiniz. HTTP üst bilgisi seçeneğini kullanan bir örneği aşağıda bulabilirsiniz (tercih edilir):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Alternatif olarak sorgu dizesi parametresi seçeneğini de kullanabilirsiniz:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Erişim jetonlarının süresi ne zaman dolar?

Google OAuth 2.0 Yetkilendirme Sunucusu tarafından verilen erişim jetonlarının süresi, expires_in değeri tarafından sağlanan sürenin ardından dolar. Bir erişim jetonunun süresi dolduğunda uygulamanın başka bir JWT oluşturması, imzalaması ve başka bir erişim jetonu istemesi gerekir.

JWT hata kodları

error alanı error_description alanı Anlamı Çözüm
unauthorized_client Unauthorized client or scope in request. Alan genelinde yetkilendirmeyi kullanmaya çalışıyorsanız hizmet hesabı, kullanıcının alanının Yönetici Konsolu'nda yetkilendirilmemiştir.

Hizmet hesabının, Yönetici Konsolu'nun Alan genelinde yetkilendirme sayfasında sub iddiasındaki (alan) kullanıcı için yetkilendirildiğinden emin olun.

Bu işlem genellikle birkaç dakika sürer ancak yetkilendirmenin Google Hesabınızdaki tüm kullanıcılara dağıtılması 24 saati bulabilir.

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. Yönetici Konsolu'nda istemci kimliği (sayısal) yerine istemci e-posta adresi kullanılarak bir hizmet hesabı yetkilendirildi. Yönetici Konsolu'ndaki Alan genelinde yetki sayfasında istemciyi kaldırın ve sayısal kimlikle yeniden ekleyin.
access_denied (herhangi bir değer) Alan genelinde yetkilendirme kullanıyorsanız istenen bir veya daha fazla kapsam Yönetici Konsolu'nda yetkilendirilmemiş olabilir.

Hizmet hesabının, Yönetici Konsolu'nun Alan genelinde yetkilendirme sayfasında sub iddiasında (alan) bulunan kullanıcı için yetkilendirildiğinden ve JWT'nizin scope iddiasında istediğiniz tüm kapsamları içerdiğinden emin olun.

Bu işlem genellikle birkaç dakika sürer ancak yetkilendirmenin Google Hesabınızdaki tüm kullanıcılara dağıtılması 24 saati bulabilir.

admin_policy_enforced (herhangi bir değer) Google Hesabı, Google Workspace yöneticisinin politikaları nedeniyle istenen bir veya daha fazla kapsamı yetkilendiremiyor.

OAuth istemci kimliğinize açıkça erişim izni verilene kadar bir yöneticinin tüm kapsamlara veya hassas ve kısıtlanmış kapsamlara erişimi nasıl kısıtlayabileceği hakkında daha fazla bilgi için Google Workspace Yöneticisi Yardım makalesindeki Google Workspace verilerine hangi üçüncü taraf uygulamalarının ve dahili uygulamaların erişebileceğini yönetme başlıklı makaleyi inceleyin.

invalid_client (herhangi bir değer)

OAuth istemcisi veya JWT jetonu geçersiz ya da yanlış yapılandırılmış.

Ayrıntılar için hata açıklamasına bakın.

JWT jetonunun geçerli olduğundan ve doğru iddiaları içerdiğinden emin olun.

OAuth istemcisinin ve hizmet hesabının doğru şekilde yapılandırıldığından ve doğru e-posta adresini kullandığınızdan emin olun.

JWT jetonunun doğru olduğundan ve istekteki istemci kimliği için oluşturulduğundan emin olun.

invalid_grant Not a valid email. Kullanıcı mevcut değil. sub claim (field) alanındaki e-posta adresinin doğru olup olmadığını kontrol edin.
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

Bu durum genellikle yerel sistem saatinin doğru olmadığı anlamına gelir. Bu durum, exp değerinin iat değerinden 65 dakikadan fazla ileride olması veya exp değerinin iat değerinden düşük olması durumunda da ortaya çıkabilir.

JWT'nin oluşturulduğu sistemdeki saatin doğru olduğundan emin olun. Gerekirse saatinizi Google NTP ile senkronize edin.

invalid_grant Invalid JWT Signature.

JWT beyanı, istemci e-postasıyla tanımlanan hizmet hesabıyla ilişkili olmayan bir özel anahtarla imzalandı veya kullanılan anahtar silindi, devre dışı bırakıldı ya da süresinin dolmasına neden oldu.

Alternatif olarak, JWT beyanı yanlış kodlanmış olabilir. Yeni satır veya eşit işareti doldurma olmadan Base64 kodlu olmalıdır.

JWT hak talebi grubunun kodunu çözerek beyanı imzalayan anahtarın hizmet hesabıyla ilişkili olduğunu doğrulayın.

JWT'nin doğru şekilde oluşturulduğundan emin olmak için Google tarafından sağlanan bir OAuth kitaplığı kullanmayı deneyin.

invalid_scope Invalid OAuth scope or ID token audience provided. Hiçbir kapsam istendi (boş kapsam listesi) veya istenen kapsamlardan biri mevcut değil (yani geçersiz).

JWT'nin scope iddiasının (alanı) doldurulduğundan emin olun ve hata veya yazım hatası olmadığından emin olmak için içerdiği kapsamları, kullanmak istediğiniz API'ler için belgelenen kapsamlarla karşılaştırın.

scope hak talebindeki kapsam listesinin virgülle değil, boşlukla ayrılması gerektiğini unutmayın.

disabled_client The OAuth client was disabled. JWT beyanını imzalamak için kullanılan anahtar devre dışıdır.

Google API Consoleadresine gidin ve IAM ve Yönetici > Hizmet Hesapları bölümünde, beyanı imzalamak için kullanılan "Anahtar Kimliği"ni içeren hizmet hesabını etkinleştirin.

org_internal This client is restricted to users within its organization. İstekte bulunan OAuth istemci kimliği, belirli bir Google Cloud kuruluşundaki Google Hesaplarına erişimi sınırlayan bir projenin parçasıdır.

Kimlik doğrulama için kuruluştaki bir hizmet hesabını kullanın. OAuth uygulamanız için kullanıcı türü yapılandırmasını onaylayın.

Ek: OAuth olmadan hizmet hesabı yetkilendirme

Bazı Google API'lerinde, OAuth 2.0 erişim jetonu yerine doğrudan sahip jetonu olarak imzalanmış bir JWT kullanarak yetkili API çağrıları yapabilirsiniz. Bu mümkün olduğunda, API çağrısı yapmadan önce Google'ın yetkilendirme sunucusuna ağ isteği göndermeniz gerekmez.

Çağırmak istediğiniz API'nin Google API'leri GitHub deposunda yayınlanmış bir hizmet tanımı varsa erişim jetonu yerine JWT kullanarak yetkili API çağrıları yapabilirsiniz. Bunu yapmak için:

  1. Yukarıda açıklandığı şekilde bir hizmet hesabı oluşturun. Hesabı oluştururken aldığınız JSON dosyasını muhafaza edin.
  2. jwt.io adresinde bulunanlar gibi standart bir JWT kitaplığı kullanarak aşağıdaki örnekteki gibi bir başlık ve yük içeren bir JWT oluşturun:
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • Başlıktaki kid alanı için hizmet hesabınızın özel anahtar kimliğini belirtin. Bu değeri, hizmet hesabı JSON dosyanızın private_key_id alanında bulabilirsiniz.
    • iss ve sub alanları için hizmet hesabınızın e-posta adresini belirtin. Bu değeri, hizmet hesabı JSON dosyanızın client_email alanında bulabilirsiniz.
    • aud alanı için API uç noktasını belirtin. Örneğin: https://SERVICE.googleapis.com/.
    • iat alanı için geçerli Unix saatini, exp alanı için ise JWT'nin süresinin dolacağının tam 3.600 saniye sonraki saatini belirtin.

Hizmet hesabı JSON dosyanızda bulunan özel anahtarı kullanarak JWT'yi RSA-256 ile imzalayın.

Örneğin:

Java

google-api-java-client ve java-jwt'i kullanarak:

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

Python

PyJWT kullanılarak:

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. Taşıyıcı jetonu olarak imzalı JWT'yi kullanarak API'yi çağırın:
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com

Hesaplar Arası Koruma'yı uygulama

Kullanıcılarınızın hesaplarını korumak için atmanız gereken bir diğer adım da Google'ın Hesaplar Arası Koruma Hizmeti'ni kullanarak Hesaplar Arası Koruma'yı uygulamaktır. Bu hizmet, kullanıcı hesabında yapılan önemli değişikliklerle ilgili olarak uygulamanıza bilgi sağlayan güvenlik etkinliği bildirimlerine abone olmanızı sağlar. Ardından, etkinliklere nasıl yanıt vermeye karar verdiğiniz doğrultusunda işlem yapmak için bu bilgileri kullanabilirsiniz.

Google'ın Hesaplar Arası Koruma Hizmeti tarafından uygulamanıza gönderilen etkinlik türlerine örnek olarak şunlar verilebilir:

  • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
  • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
  • https://schemas.openid.net/secevent/risc/event-type/account-disabled

Hesaplar Arası Koruma'nın nasıl uygulanacağı ve mevcut etkinliklerin tam listesi hakkında daha fazla bilgi için Hesaplar Arası Koruma ile kullanıcı hesaplarını koruma sayfasına bakabilirsiniz.