Bu dokümanda, web sunucusu uygulamalarının Google API'lerine erişmek için OAuth 2.0 yetkilendirmesini uygulamak amacıyla Google API istemci kitaplıklarını veya Google OAuth 2.0 uç noktalarını nasıl kullandığı açıklanmaktadır.
OAuth 2.0 sayesinde kullanıcılar, bir uygulamayla belirli verileri paylaşırken kullanıcı adlarını, şifrelerini ve diğer bilgilerini gizli tutabilir. Örneğin, bir uygulama, kullanıcılardan Google Drive'larında dosya depolama izni almak için OAuth 2.0'ı kullanabilir.
Bu OAuth 2.0 akışı, özellikle kullanıcı yetkilendirmesi içindir. Gizli bilgileri saklayabilen ve durumu koruyabilen uygulamalar için tasarlanmıştır. Düzgün şekilde yetkilendirilmiş bir web sunucusu uygulaması, kullanıcı uygulamayla etkileşimde bulunurken veya kullanıcı uygulamadan ayrıldıktan sonra bir API'ye erişebilir.
Web sunucusu uygulamaları, API isteklerini yetkilendirmek için genellikle hizmet hesaplarını da kullanır. Özellikle kullanıcıya özel veriler yerine projeye dayalı verilere erişmek için Cloud API'lerini çağırırken bu yöntem tercih edilir. Web sunucusu uygulamaları, hizmet hesaplarını kullanıcı yetkilendirmesiyle birlikte kullanabilir.
İstemci kitaplıkları
Bu sayfada yer alan dile özgü örneklerde, OAuth 2.0 yetkilendirmesini uygulamak için Google API istemci kitaplıkları kullanılır. Kod örneklerini çalıştırmak için öncelikle dilinize yönelik istemci kitaplığını yüklemeniz gerekir.
Uygulamanızın OAuth 2.0 akışını yönetmek için bir Google API istemci kitaplığı kullandığınızda istemci kitaplığı, uygulamanın kendi başına yapması gereken birçok işlemi gerçekleştirir. Örneğin, uygulamanın depolanan erişim jetonlarını ne zaman kullanabileceğini veya yenileyebileceğini ve uygulamanın ne zaman yeniden izin alması gerektiğini belirler. Müşteri kitaplığı, doğru yönlendirme URL'lerini de oluşturur ve erişim jetonları için yetkilendirme kodları değiştiren yönlendirme işleyicilerinin uygulanmasına yardımcı olur.
Sunucu tarafı uygulamalar için Google API istemci kitaplıkları aşağıdaki dillerde kullanılabilir:
Ön koşullar
Projeniz için API'leri etkinleştirme
Google API'lerini çağıran tüm uygulamaların bu API'leri API Console'te etkinleştirmesi gerekir.
Projeniz için bir API'yi etkinleştirmek üzere:
- Open the API Library , Google API Console
- If prompted, select a project, or create a new one.
- Bu API Library sayfada, ürün ailesine ve popülerliğe göre gruplandırılmış tüm mevcut API'ler listelenir. Etkinleştirmek istediğiniz API listede görünmüyorsa arama yaparak bulabilir veya ait olduğu ürün ailesinde Tümünü Görüntüle'yi tıklayabilirsiniz.
- Etkinleştirmek istediğiniz API'yi seçin ve ardından Etkinleştir düğmesini tıklayın.
- If prompted, enable billing.
- If prompted, read and accept the API's Terms of Service.
Yetkilendirme kimlik bilgileri oluşturma
Google API'lerine erişmek için OAuth 2.0 kullanan tüm uygulamaların, Google'ın OAuth 2.0 sunucusunda uygulamayı tanımlayan yetkilendirme kimlik bilgilerine sahip olması gerekir. Aşağıdaki adımlarda, projeniz için kimlik bilgilerinin nasıl oluşturulacağı açıklanmaktadır. Ardından, uygulamalarınız bu proje için etkinleştirdiğiniz API'lere erişmek üzere kimlik bilgilerini kullanabilir.
- Go to the Credentials page.
- Kimlik bilgisi oluştur > OAuth istemci kimliği seçeneğini tıklayın.
- Web uygulaması uygulama türünü seçin.
- Formu doldurup Oluştur'u tıklayın. PHP, Java, Python, Ruby ve .NET gibi dilleri ve çerçeveleri kullanan uygulamalar, yetkili yönlendirme URI'lerini belirtmelidir. Yönlendirme URI'leri, OAuth 2.0 sunucusunun yanıt gönderebileceği uç noktalardır. Bu uç noktalar Google'ın doğrulama kurallarına uygun olmalıdır.
Test için yerel makineye atıfta bulunan URI'leri (ör.
http://localhost:8080
) belirtebilirsiniz. Bu nedenle, bu dokümandaki tüm örneklerde yönlendirme URI'si olarakhttp://localhost:8080
kullanıldığını lütfen unutmayın.Uygulamanızın yetkilendirme kodlarını sayfadaki diğer kaynaklara göstermemesi için uygulamanızın yetkilendirme uç noktalarını tasarlamanızı öneririz.
Kimlik bilgilerinizi oluşturduktan sonra client_secret.json dosyasını API Consoleadresinden indirin. Dosyayı yalnızca uygulamanızın erişebileceği bir konumda güvenli bir şekilde saklayın.
Erişim kapsamlarını belirleme
Kapsamlar, uygulamanızın yalnızca ihtiyaç duyduğu kaynaklara erişim isteğinde bulunmasını sağlarken kullanıcıların da uygulamanıza verdikleri erişim miktarını kontrol etmelerini sağlar. Bu nedenle, istenen kapsamların sayısı ile kullanıcı izni alma olasılığı arasında ters bir ilişki olabilir.
OAuth 2.0 yetkilendirmesini uygulamaya başlamadan önce, uygulamanızın erişmek için izin alması gereken kapsamları belirlemenizi öneririz.
Ayrıca, uygulamanızın, kullanıcı verilerine bağlam içinde erişim izni istediği bir artımlı yetkilendirme süreci aracılığıyla yetkilendirme kapsamlarına erişim isteğinde bulunmasını öneririz. Bu en iyi uygulama, kullanıcıların uygulamanızın istenen erişime neden ihtiyaç duyduğunu daha kolay anlamasına yardımcı olur.
OAuth 2.0 API Kapsamları belgesi, Google API'lerine erişmek için kullanabileceğiniz kapsamların tam listesini içerir.
Dile özgü şartlar
Bu belgedeki kod örneklerinden herhangi birini çalıştırmak için bir Google Hesabı, internete erişiminiz ve bir web tarayıcınız olmalıdır. API istemci kitaplıklarından birini kullanıyorsanız aşağıdaki dile özgü gereksinimlere de bakın.
PHP
Bu belgedeki PHP kod örneklerini çalıştırmak için şunlar gerekir:
- Komut satırı arayüzü (KSA) ve JSON uzantısı yüklü PHP 8.0 veya sonraki bir sürüm.
- Composer bağımlılık yönetimi aracı.
-
PHP için Google API'leri istemci kitaplığı:
composer require google/apiclient:^2.15.0
Daha fazla bilgi için PHP için Google API'leri İstemci Kitaplığı başlıklı makaleyi inceleyin.
Python
Bu belgedeki Python kod örneklerini çalıştırmak için şunlar gerekir:
- Python 3.7 veya üzeri
- pip paket yönetim aracı.
- Python 2.0 için Google API'leri istemci kitaplığı sürümü:
pip install --upgrade google-api-python-client
- Kullanıcı yetkilendirmesi için
google-auth
,google-auth-oauthlib
vegoogle-auth-httplib2
.pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
- Flask Python web uygulaması çerçevesi.
pip install --upgrade flask
requests
HTTP kitaplığı.pip install --upgrade requests
Python'u yükseltemiyor ve ilişkili taşıma kılavuzunu kullanamıyorsanız Google API Python istemci kitaplığı sürüm notunu inceleyin.
Ruby
Bu belgedeki Ruby kod örneklerini çalıştırmak için şunlar gerekir:
- Ruby 2.6 veya üzeri
-
Ruby için Google Kimlik Doğrulama Kitaplığı:
gem install googleauth
-
Drive ve Takvim Google API'leri için istemci kitaplıkları:
gem install google-apis-drive_v3 google-apis-calendar_v3
-
Sinatra Ruby web uygulaması çerçevesi.
gem install sinatra
Node.js
Bu dokümandaki Node.js kod örneklerini çalıştırmak için şunlar gerekir:
- Bakım LTS, etkin LTS veya Node.js'in mevcut sürümü.
-
Google API'leri Node.js İstemcisi:
npm install googleapis crypto express express-session
HTTP/REST
OAuth 2.0 uç noktalarını doğrudan çağırabilmek için herhangi bir kitaplık yüklemeniz gerekmez.
OAuth 2.0 erişim jetonları alma
Aşağıdaki adımlarda, uygulamanızın kullanıcı adına API isteği gerçekleştirmek için kullanıcının iznini almak amacıyla Google'ın OAuth 2.0 sunucusuyla nasıl etkileşimde bulunduğu gösterilmektedir. Kullanıcı yetkilendirmesi gerektiren bir Google API isteğini yürütebilmesi için uygulamanızın bu izne sahip olması gerekir.
Aşağıdaki listede bu adımlar kısaca özetlenmiştir:
- Uygulamanız, ihtiyaç duyduğu izinleri tanımlar.
- Uygulamanız, kullanıcıyı istenen izinlerin listesiyle birlikte Google'a yönlendirir.
- Uygulamanıza izin verilip verilmeyeceğine kullanıcı karar verir.
- Uygulamanız, kullanıcının neye karar verdiğini öğrenir.
- Kullanıcı istenen izinleri verdiyse uygulamanız, kullanıcı adına API isteği göndermek için gereken jetonları alır.
1. adım: Yetkilendirme parametrelerini ayarlayın
İlk adımınız, yetkilendirme isteğini oluşturmaktır. Bu istek, uygulamanızı tanımlayan ve kullanıcıdan uygulamanıza vermesi istenen izinleri tanımlayan parametreleri belirler.
- OAuth 2.0 kimlik doğrulaması ve yetkilendirme için bir Google istemci kitaplığı kullanıyorsanız bu parametreleri tanımlayan bir nesne oluşturup yapılandırırsınız.
- Google OAuth 2.0 uç noktasını doğrudan çağırırsanız bir URL oluşturur ve bu URL'deki parametreleri ayarlarsınız.
Aşağıdaki sekmelerde, web sunucusu uygulamaları için desteklenen yetkilendirme parametreleri tanımlanmaktadır. Dile özgü örneklerde, bu parametreleri ayarlayan bir nesneyi yapılandırmak için istemci kitaplığının veya yetkilendirme kitaplığının nasıl kullanılacağı da gösterilir.
PHP
Aşağıdaki kod snippet'i, yetkilendirme isteklerindeki parametreleri tanımlayan bir Google\Client()
nesnesi oluşturur.
Bu nesne, uygulamanızı tanımlamak için client_secret.json dosyanızdaki bilgileri kullanır. (Bu dosya hakkında daha fazla bilgi için yetkilendirme kimlik bilgileri oluşturma başlıklı makaleyi inceleyin.) Nesne ayrıca, uygulamanızın erişim izni istediği kapsamları ve Google'ın OAuth 2.0 sunucusundan gelen yanıtı işleyen uygulamanızın kimlik doğrulama uç noktasının URL'sini de tanımlar. Son olarak kod, isteğe bağlı access_type
ve include_granted_scopes
parametrelerini ayarlar.
Örneğin, bu kod bir kullanıcının Google Drive meta verilerine ve Takvim etkinliklerine salt okuma, çevrimdışı erişim isteğinde bulunur:
use Google\Client; $client = new Client(); // Required, call the setAuthConfig function to load authorization credentials from // client_secret.json file. $client->setAuthConfig('client_secret.json'); // Required, to set the scope value, call the addScope function $client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]); // Required, call the setRedirectUri function to specify a valid redirect URI for the // provided client_id $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); // Recommended, offline access will give you both an access and refresh token so that // your app can refresh the access token without user interaction. $client->setAccessType('offline'); // Recommended, call the setState function. Using a state value can increase your assurance that // an incoming connection is the result of an authentication request. $client->setState($sample_passthrough_value); // Optional, if your application knows which user is trying to authenticate, it can use this // parameter to provide a hint to the Google Authentication Server. $client->setLoginHint('hint@example.com'); // Optional, call the setPrompt function to set "consent" will prompt the user for consent $client->setPrompt('consent'); // Optional, call the setIncludeGrantedScopes function with true to enable incremental // authorization $client->setIncludeGrantedScopes(true);
Python
Aşağıdaki kod snippet'inde, yetkilendirme isteğini oluşturmak için google-auth-oauthlib.flow
modülü kullanılmaktadır.
Kod, yetkilendirme kimlik bilgilerini oluşturduktan sonra indirdiğiniz client_secret.json dosyasından alınan bilgileri kullanarak uygulamanızı tanımlayan bir Flow
nesnesi oluşturur. Bu nesne, uygulamanızın erişim izni istediği kapsamları ve uygulamanızın kimlik doğrulama uç noktasının URL'sini de tanımlar. Bu URL, Google'ın OAuth 2.0 sunucusundan gelen yanıtı işler. Son olarak kod, isteğe bağlı access_type
ve include_granted_scopes
parametrelerini ayarlar.
Örneğin, bu kod bir kullanıcının Google Drive meta verilerine ve Takvim etkinliklerine salt okuma, çevrimdışı erişim isteğinde bulunur:
import google.oauth2.credentials import google_auth_oauthlib.flow # Required, call the from_client_secrets_file method to retrieve the client ID from a # client_secret.json file. The client ID (from that file) and access scopes are required. (You can # also use the from_client_config method, which passes the client configuration as it originally # appeared in a client secrets file but doesn't access the file itself.) flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file('client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/calendar.readonly']) # Required, indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. flow.redirect_uri = 'https://www.example.com/oauth2callback' # Generate URL for request to Google's OAuth 2.0 server. # Use kwargs to set optional request parameters. authorization_url, state = flow.authorization_url( # Recommended, enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Optional, enable incremental authorization. Recommended as a best practice. include_granted_scopes='true', # Optional, if your application knows which user is trying to authenticate, it can use this # parameter to provide a hint to the Google Authentication Server. login_hint='hint@example.com', # Optional, set prompt to 'consent' will prompt the user for consent prompt='consent')
Ruby
Uygulamanızda bir istemci nesnesi yapılandırmak için oluşturduğunuz client_secrets.json dosyasını kullanın. Bir istemci nesnesini yapılandırırken, uygulamanızın erişmesi gereken kapsamları ve OAuth 2.0 sunucusundan gelen yanıtı işleyen uygulamanızın kimlik doğrulama uç noktasının URL'sini belirtirsiniz.
Örneğin, bu kod bir kullanıcının Google Drive meta verilerine ve Takvim etkinliklerine salt okuma, çevrimdışı erişim isteğinde bulunur:
require 'googleauth' require 'googleauth/web_user_authorizer' require 'googleauth/stores/redis_token_store' require 'google/apis/drive_v3' require 'google/apis/calendar_v3' # Required, call the from_file method to retrieve the client ID from a # client_secret.json file. client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json') # Required, scope value # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar. scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY', 'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY'] # Required, Authorizers require a storage instance to manage long term persistence of # access and refresh tokens. token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) # Required, indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. callback_uri = '/oauth2callback' # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI # from the client_secret.json file. To get these credentials for your application, visit # https://console.cloud.google.com/apis/credentials. authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, callback_uri)
Uygulamanız, yetkilendirme isteği URL'leri oluşturma ve HTTP isteklerine erişim jetonları uygulama gibi OAuth 2.0 işlemlerini gerçekleştirmek için istemci nesnesini kullanır.
Node.js
Aşağıdaki kod snippet'i, yetkilendirme isteklerindeki parametreleri tanımlayan bir google.auth.OAuth2
nesnesi oluşturur.
Bu nesne, uygulamanızı tanımlamak için client_secret.json dosyanızdaki bilgileri kullanır. Bir kullanıcıdan erişim jetonu almak için izin istemek amacıyla kullanıcıyı bir izin sayfasına yönlendirirsiniz. Kullanıcı rızası sayfası URL'si oluşturmak için:
const {google} = require('googleapis'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI * from the client_secret.json file. To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/calendar.readonly' ]; // Generate a secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // Generate a url that asks permissions for the Drive activity and Google Calendar scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true, // Include the state parameter to reduce the risk of CSRF attacks. state: state });
Önemli Not: refresh_token
yalnızca ilk yetkilendirmede döndürülür. Daha fazla bilgiyi
burada bulabilirsiniz.
HTTP/REST
Google'ın OAuth 2.0 uç noktası https://accounts.google.com/o/oauth2/v2/auth
adresindedir. Bu uç noktaya yalnızca HTTPS üzerinden erişilebilir. Basit HTTP bağlantıları reddedilir.
Google yetkilendirme sunucusu, web sunucusu uygulamaları için aşağıdaki sorgu dizesi parametrelerini destekler:
Parametreler | |||||||
---|---|---|---|---|---|---|---|
client_id |
Zorunlu
Uygulamanızın istemci kimliği. Bu değeri şu adreste bulabilirsiniz: API Console Credentials page. |
||||||
redirect_uri |
Zorunlu
Kullanıcı yetkilendirme akışını tamamladıktan sonra API sunucusunun kullanıcıyı nereye yönlendireceğini belirler. Değer, OAuth 2.0 istemcisi için yetkili yönlendirme URI'lerinden biriyle tam olarak eşleşmelidir. Bu URI'yi istemcinizin API Console
Credentials pagebölümünde yapılandırdınız. Bu değer, sağlanan
|
||||||
response_type |
Zorunlu
Google OAuth 2.0 uç noktasının yetkilendirme kodu döndürüp döndürmeyeceğini belirler. Web sunucusu uygulamaları için parametre değerini |
||||||
scope |
Zorunlu
Uygulamanızın kullanıcı adına erişebileceği kaynakları tanımlayan, boşlukla ayrılmış bir kapsam listesi. Bu değerler, Google'ın kullanıcıya gösterdiği izin ekranını bilgilendirir. Kapsamlar, uygulamanızın yalnızca ihtiyaç duyduğu kaynaklara erişim isteğinde bulunmasını sağlar. Ayrıca kullanıcıların, uygulamanıza verdikleri erişim miktarını kontrol etmelerini de sağlar. Bu nedenle, istenen kapsamların sayısı ile kullanıcı izni alma olasılığı arasında ters bir ilişki vardır. Uygulamanızın, mümkün olduğunda bağlama göre yetkilendirme kapsamlarına erişim isteğinde bulunmasını öneririz. Artımlı yetkilendirme aracılığıyla kullanıcı verilerine bağlam içinde erişim isteğinde bulunarak kullanıcıların, uygulamanızın istediği erişime neden ihtiyaç duyduğunu daha kolay anlamalarına yardımcı olursunuz. |
||||||
access_type |
Önerilen
Kullanıcı tarayıcıda değilken uygulamanızın erişim jetonlarını yenileyip yenileyemeyeceğini belirtir. Geçerli parametre değerleri varsayılan değer olan Uygulamanızın, kullanıcı tarayıcıda değilken erişim jetonlarını yenilemesi gerekiyorsa değeri |
||||||
state |
Önerilen
Uygulamanızın, yetkilendirme isteğiniz ile yetkilendirme sunucusunun yanıtı arasında durumu korumak için kullandığı tüm dize değerlerini belirtir.
Sunucu, kullanıcı uygulamanızın erişim isteğini onayladıktan veya reddettikten sonra Bu parametreyi, kullanıcıyı uygulamanızdaki doğru kaynağa yönlendirme, tek seferlik kimlikler gönderme ve siteler arası istek sahteciliğini azaltma gibi çeşitli amaçlar için kullanabilirsiniz. |
||||||
include_granted_scopes |
İsteğe bağlı
Uygulamaların, bağlamda ek kapsamlara erişim isteğinde bulunmak için artımlı yetkilendirmeyi kullanmasına olanak tanır. Bu parametrenin değerini |
||||||
enable_granular_consent |
İsteğe bağlı
Varsayılan olarak Google bir uygulama için ayrıntılı izinleri etkinleştirdiğinde bu parametrenin artık etkisi olmaz. |
||||||
login_hint |
İsteğe bağlı
Uygulamanız hangi kullanıcının kimliğini doğrulamaya çalıştığını biliyorsa Google Kimlik Doğrulama Sunucusu'na ipucu vermek için bu parametreyi kullanabilir. Sunucu, oturum açma formundaki e-posta alanını önceden doldurarak veya uygun çoklu oturum oturumunu seçerek oturum açma akışını basitleştirmek için ipucunu kullanır. Parametre değerini, kullanıcının Google kimliğine eşdeğer olan bir e-posta adresine veya |
||||||
prompt |
İsteğe bağlı
Kullanıcıya gösterilecek istemlerin boşlukla ayrılmış, büyük/küçük harfe duyarlı listesi. Bu parametreyi belirtmezseniz kullanıcıdan yalnızca projeniz ilk kez erişim istediğinde izin istenir. Daha fazla bilgi için Yeniden izin isteğinde bulunma başlıklı makaleyi inceleyin. Olası değerler:
|
2. adım: Google'ın OAuth 2.0 sunucusuna yönlendirme
Kimlik doğrulama ve yetkilendirme sürecini başlatmak için kullanıcıyı Google'ın OAuth 2.0 sunucusuna yönlendirin. Bu durum genellikle uygulamanızın kullanıcı verilerine ilk kez erişmesi gerektiğinde ortaya çıkar. Artımlı yetkilendirme söz konusu olduğunda bu adım, uygulamanızın henüz erişme izni olmayan ek kaynaklara ilk kez erişmesi gerektiğinde de gerçekleşir.
PHP
- Google'ın OAuth 2.0 sunucusundan erişim isteğinde bulunmak için bir URL oluşturun:
$auth_url = $client->createAuthUrl();
- Kullanıcıyı
$auth_url
adresine yönlendirin:header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
Python
Bu örnekte, Flask web uygulama çerçevesi kullanılarak kullanıcının yetkilendirme URL'sine nasıl yönlendirileceği gösterilmektedir:
return flask.redirect(authorization_url)
Ruby
- Google'ın OAuth 2.0 sunucusundan erişim isteğinde bulunmak için bir URL oluşturun:
auth_uri = authorizer.get_authorization_url(request: request)
- Kullanıcıyı
auth_uri
adresine yönlendirin.
Node.js
-
Google'ın OAuth 2.0 sunucusundan erişim isteğinde bulunmak için 1. adımdaki
generateAuthUrl
yönteminde oluşturulan URL'yiauthorizationUrl
kullanın. -
Kullanıcıyı
authorizationUrl
adresine yönlendirin.res.redirect(authorizationUrl);
HTTP/REST
Sample redirect to Google's authorization server
An example URL is shown below, with line breaks and spaces for readability.
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly& access_type=offline& include_granted_scopes=true& response_type=code& state=state_parameter_passthrough_value& redirect_uri=https%3A//oauth2.example.com/code& client_id=client_id
İstek URL'sini oluşturduktan sonra kullanıcıyı bu URL'ye yönlendirin.
Google'ın OAuth 2.0 sunucusu kullanıcının kimliğini doğrular ve uygulamanızın istenen kapsamlara erişmesi için kullanıcıdan izin alır. Yanıt, belirttiğiniz yönlendirme URL'si kullanılarak uygulamanıza geri gönderilir.
3. Adım: Google, kullanıcıdan izin ister.
Bu adımda kullanıcı, uygulamanıza istenen erişimi verip vermeyeceğine karar verir. Bu aşamada Google, uygulamanızın adını ve kullanıcının yetkilendirme kimlik bilgileriyle erişim izni istediği Google API hizmetlerini gösteren bir izin penceresi ile birlikte, verilecek erişim kapsamlarının bir özetini gösterir. Kullanıcı, uygulamanız tarafından istenen bir veya daha fazla kapsama erişim izni vermeyi kabul edebilir ya da isteği reddedebilir.
Google'ın OAuth 2.0 sunucusundan erişim izni verilip verilmediğini belirten yanıtı beklerken uygulamanızın bu aşamada herhangi bir işlem yapması gerekmez. Bu yanıt, aşağıdaki adımda açıklanmıştır.
Hatalar
Google'ın OAuth 2.0 yetkilendirme uç noktasına yapılan istekler, beklenen kimlik doğrulama ve yetkilendirme akışları yerine kullanıcılara yönelik hata mesajları gösterebilir. Sık karşılaşılan hata kodları ve önerilen çözümler aşağıda listelenmiştir.
admin_policy_enforced
Google Hesabı, Google Workspace yöneticisinin politikaları nedeniyle istenen bir veya daha fazla kapsamı yetkilendiremiyor. Bir yöneticinin, OAuth istemci kimliğinize açıkça erişim izni verilene kadar 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 makalesini Google Workspace verilerine hangi üçüncü taraf uygulamalarının ve dahili uygulamaların erişebileceğini yönetme inceleyin.
disallowed_useragent
Yetkilendirme uç noktası, Google'ın OAuth 2.0 Politikaları tarafından izin verilmeyen yerleşik bir kullanıcı aracısı içinde gösteriliyor.
Yapay Zeka
Android geliştiricileri, android.webkit.WebView
'te yetkilendirme isteklerini açarken bu hata mesajıyla karşılaşabilir.
Geliştiriciler bunun yerine Android için Google ile Oturum Açma veya OpenID Foundation'ın Android için AppAuth gibi Android kitaplıklarını kullanmalıdır.
Web geliştiricileri, bir Android uygulaması yerleşik bir kullanıcı aracısında genel bir web bağlantısı açtığında ve bir kullanıcı sitenizden Google'ın OAuth 2.0 yetkilendirme uç noktasına gittiğinde bu hatayla karşılaşabilir. Geliştiriciler, genel bağlantıların işletim sisteminin varsayılan bağlantı işleyicisinde açılmasına izin vermelidir. Bu işleyiciler hem Android Uygulama Bağlantıları işleyicilerini hem de varsayılan tarayıcı uygulamasını içerir. Android Özel Sekmeler kitaplığı da desteklenen bir seçenektir.
iOS
iOS ve macOS geliştiricileri, WKWebView
'te yetkilendirme isteklerini açarken bu hatayla karşılaşabilir.
Geliştiriciler bunun yerine iOS için Google ile oturum açma veya OpenID Foundation'ın iOS için AppAuth gibi iOS kitaplıklarını kullanmalıdır.
Web geliştiricileri, bir iOS veya macOS uygulaması yerleşik bir kullanıcı aracısında genel bir web bağlantısı açtığında ve bir kullanıcı sitenizden Google'ın OAuth 2.0 yetkilendirme uç noktasına gittiğinde bu hatayla karşılaşabilir. Geliştiriciler, genel bağlantıların işletim sisteminin varsayılan bağlantı işleyicisinde açılmasına izin vermelidir. Bu işleyiciler hem Evrensel Bağlantılar işleyicilerini hem de varsayılan tarayıcı uygulamasını içerir. SFSafariViewController
kitaplığı da desteklenen bir seçenektir.
org_internal
İstekte bulunan OAuth istemci kimliği, belirli bir Google Cloud kuruluşunda Google Hesaplarına erişimi sınırlayan bir projenin parçasıdır. Bu yapılandırma seçeneği hakkında daha fazla bilgi edinmek için OAuth izin ekranınızı ayarlama yardım makalesindeki Kullanıcı türü bölümüne bakın.
invalid_client
OAuth istemci sırrı yanlış. Bu istek için kullanılan istemci kimliği ve gizli anahtar da dahil olmak üzere OAuth istemci yapılandırmasını inceleyin.
invalid_grant
Erişim jetonunu yenilerken veya artımlı yetkilendirme kullanılırken jetonun süresi dolmuş veya geçersiz kılınmış olabilir. Kullanıcının kimliğini tekrar doğrulayın ve yeni jeton almak için kullanıcıdan izin isteyin. Bu hatayı görmeye devam ediyorsanız uygulamanızın doğru şekilde yapılandırıldığından ve isteğinizde doğru jetonları ve parametreleri kullandığınızdan emin olun. Aksi takdirde, kullanıcı hesabı silinmiş veya devre dışı bırakılmış olabilir.
redirect_uri_mismatch
Yetkilendirme isteğinde iletilen redirect_uri
, OAuth istemci kimliği için yetkili bir yönlendirme URI'siyle eşleşmiyor. Google API Console Credentials pagebölümündeki yetkili yönlendirme URI'lerini inceleyin.
redirect_uri
parametresi, kullanımdan kaldırılmış ve artık desteklenmeyen OAuth bant dışı (OOB) akışını referans alabilir. Entegrasyonunuzu güncellemek için taşıma kılavuzunu inceleyin.
invalid_request
Gönderdiğiniz istekte bir sorun vardı. Bunun birkaç nedeni olabilir:
- İstek doğru şekilde biçimlendirilmemiş
- İstekte gerekli parametreler eksik
- İstek, Google'ın desteklemediği bir yetkilendirme yöntemi kullanıyor. OAuth entegrasyonunuzun önerilen bir entegrasyon yöntemini kullandığından emin olun
4. adım: OAuth 2.0 sunucu yanıtını işleyin
OAuth 2.0 sunucusu, istekte belirtilen URL'yi kullanarak uygulamanızın erişim isteğine yanıt verir.
Kullanıcı erişim isteğini onaylarsa yanıtta bir yetkilendirme kodu bulunur. Kullanıcı isteği onaylamıyorsa yanıtta bir hata mesajı yer alır. Web sunucusuna döndürülen yetkilendirme kodu veya hata mesajı, sorgu dizesinde aşağıdaki gibi görünür:
Hata yanıtı:
https://oauth2.example.com/auth?error=access_denied
Yetkilendirme kodu yanıtı:
https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7
Örnek OAuth 2.0 sunucu yanıtı
Aşağıdaki örnek URL'yi tıklayarak bu akışı test edebilirsiniz. Bu URL, Google Drive'ınızdaki dosyaların meta verilerini görüntülemek için salt okunur erişim ve Google Takvim etkinliklerinizi görüntülemek için salt okunur erişim ister:
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly& access_type=offline& include_granted_scopes=true& response_type=code& state=state_parameter_passthrough_value& redirect_uri=https%3A//oauth2.example.com/code& client_id=client_id
OAuth 2.0 akışı tamamlandıktan sonra http://localhost/oauth2callback
adresine yönlendirilirsiniz. Yerel makineniz bu adreste bir dosya sunmadığı sürece muhtemelen 404 NOT FOUND
hatası alırsınız. Bir sonraki adımda, kullanıcı uygulamanıza geri yönlendirildiğinde URI'de döndürülen bilgiler hakkında daha fazla ayrıntı sağlanmaktadır.
5. Adım: Yenileme ve erişim jetonları için yetkilendirme kodu değiş tokuşu yapın
Web sunucusu, yetkilendirme kodunu aldıktan sonra bu kodu bir erişim jetonuyla değiştirebilir.
PHP
Yetkilendirme kodunu erişim jetonuyla değiştirmek için fetchAccessTokenWithAuthCode
yöntemini kullanın:
$access_token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
Python
Geri çağırma sayfanızda, yetkilendirme sunucusu yanıtını doğrulamak için google-auth
kitaplığını kullanın. Ardından, bu yanıttaki yetkilendirme kodunu erişim jetonuyla değiştirmek için flow.fetch_token
yöntemini kullanın:
state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'], state=state) flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store the credentials in the session. # ACTION ITEM for developers: # Store user's access and refresh tokens in your data store if # incorporating this code into your real app. credentials = flow.credentials flask.session['credentials'] = { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'granted_scopes': credentials.granted_scopes}
Ruby
Geri çağırma sayfanızda, yetkilendirme sunucusu yanıtını doğrulamak için googleauth
kitaplığını kullanın. Yetkilendirme kodunu kaydetmek ve ilk başta yetkilendirme isteğinde bulunan URL'ye geri yönlendirmek için authorizer.handle_auth_callback_deferred
yöntemini kullanın. Bu, sonuçları kullanıcının oturumuna geçici olarak ekleyerek kodun değişimini erteler.
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url
Node.js
Yetkilendirme kodunu erişim jetonuyla değiştirmek için getToken
yöntemini kullanın:
const url = require('url'); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); });
HTTP/REST
Yetkilendirme kodunu erişim jetonuyla değiştirmek için https://oauth2.googleapis.com/token
uç noktasını çağırın ve aşağıdaki parametreleri ayarlayın:
Alanlar | |
---|---|
client_id |
API Console Credentials pageadresinden alınan istemci kimliği. |
client_secret |
API Console Credentials pageadresinden alınan istemci gizli anahtarı. |
code |
İlk istekten döndürülen yetkilendirme kodu. |
grant_type |
OAuth 2.0 spesifikasyonunda tanımlandığı şekliyle bu alanın değeri authorization_code olarak ayarlanmalıdır. |
redirect_uri |
Belirli bir client_id için API Consolebölümündeki projeniz için listelenen yönlendirme URI'lerinden biri
Credentials page . |
Aşağıdaki snippet'te örnek bir istek gösterilmektedir:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& client_secret=your_client_secret& redirect_uri=https%3A//oauth2.example.com/code& grant_type=authorization_code
Google, bu isteğe kısa süreli bir erişim jetonu ve yenileme jetonu içeren bir JSON nesnesi döndürerek yanıt verir.
Yenileme jetonunun yalnızca uygulamanız Google'ın yetkilendirme sunucusuna gönderilen ilk istekte access_type
parametresini offline
olarak ayarlarsa döndürüleceğini unutmayın.
Yanıtta aşağıdaki alanlar bulunur:
Alanlar | |
---|---|
access_token |
Uygulamanızın, bir Google API isteğini yetkilendirmek için gönderdiği jeton. |
expires_in |
Erişim jetonunun kalan kullanım ömrü (saniye cinsinden). |
refresh_token |
Yeni bir erişim jetonu almak için kullanabileceğiniz jeton. Yenileme jetonları, kullanıcı erişimi iptal edene kadar geçerlidir.
Yine de bu alan yalnızca Google'ın yetkilendirme sunucusuna gönderilen ilk istekte access_type parametresini offline olarak ayarlarsanız bu yanıtta bulunur.
|
scope |
access_token tarafından verilen erişim kapsamları, boşlukla ayrılmış, büyük/küçük harfe duyarlı dizelerin listesi olarak ifade edilir. |
token_type |
Döndürülen jeton türü. Bu aşamada bu alanın değeri her zaman Bearer olarak ayarlanır. |
Aşağıdaki snippet'te örnek bir yanıt gösterilmektedir:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
Hatalar
Yetkilendirme kodunu erişim jetonuyla değiştirirken beklenen yanıt yerine aşağıdaki hatayla karşılaşabilirsiniz. Sık karşılaşılan hata kodları ve önerilen çözümler aşağıda listelenmiştir.
invalid_grant
Sağlanan yetkilendirme kodu geçersiz veya yanlış biçimde. Kullanıcıdan tekrar izin istemek için OAuth sürecini yeniden başlatarak yeni bir kod isteyin.
6. adım: Kullanıcıların hangi kapsamları verdiğini kontrol edin
Tek seferde birden fazla kapsam isteğinde bulunurken kullanıcılar, uygulamanızın istediği tüm kapsamları vermeyebilir. Uygulamanız her zaman kullanıcı tarafından hangi kapsamların verildiğini kontrol etmeli ve ilgili özellikleri devre dışı bırakarak kapsamların reddedilmesini ele almalıdır. Daha fazla bilgi için Ayrıntılı izinleri yönetme başlıklı makaleyi inceleyin.
PHP
Kullanıcının hangi kapsamları izin verdiğini kontrol etmek için getGrantedScope()
yöntemini kullanın:
// Space-separated string of granted scopes if it exists, otherwise null. $granted_scopes = $client->getOAuth2Service()->getGrantedScope(); // Determine which scopes user granted and build a dictionary $granted_scopes_dict = [ 'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY), 'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY) ];
Python
Döndürülen credentials
nesnesinde, kullanıcının uygulamanıza verdiği kapsamların listesi olan bir granted_scopes
mülkü bulunur.
credentials = flow.credentials flask.session['credentials'] = { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'granted_scopes': credentials.granted_scopes}
Aşağıdaki işlev, kullanıcının uygulamanıza hangi kapsamları verdiğini kontrol eder.
def check_granted_scopes(credentials): features = {} if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']: features['drive'] = True else: features['drive'] = False if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']: features['calendar'] = True else: features['calendar'] = False return features
Ruby
Aynı anda birden fazla kapsam isteğinde bulunurken credentials
nesnesinin scope
mülkü aracılığıyla hangi kapsamların verildiğini kontrol edin.
# User authorized the request. Now, check which scopes were granted. if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY) # User authorized read-only Drive activity permission. # Calling the APIs, etc else # User didn't authorize read-only Drive activity permission. # Update UX and application accordingly end # Check if user authorized Calendar read permission. if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY) # User authorized Calendar read permission. # Calling the APIs, etc. else # User didn't authorize Calendar read permission. # Update UX and application accordingly end
Node.js
Aynı anda birden fazla kapsam isteğinde bulunurken tokens
nesnesinin scope
mülkü aracılığıyla hangi kapsamların verildiğini kontrol edin.
// User authorized the request. Now, check which scopes were granted. if (tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly')) { // User authorized read-only Drive activity permission. // Calling the APIs, etc. } else { // User didn't authorize read-only Drive activity permission. // Update UX and application accordingly } // Check if user authorized Calendar read permission. if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly')) { // User authorized Calendar read permission. // Calling the APIs, etc. } else { // User didn't authorize Calendar read permission. // Update UX and application accordingly }
HTTP/REST
Kullanıcının uygulamanıza belirli bir kapsama erişim izni verip vermediğini kontrol etmek için erişim jetonu yanıtındaki scope
alanını inceleyin. access_token tarafından verilen erişim kapsamları, boşlukla ayrılmış, büyük/küçük harf duyarlı dizelerin listesi olarak ifade edilir.
Örneğin, aşağıdaki örnek erişim jetonu yanıtı, kullanıcının uygulamanıza salt okunur Drive etkinliği ve Takvim etkinlikleri izinlerine erişim izni verdiğini gösterir:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
Google API'lerini çağırma
PHP
Aşağıdaki adımları uygulayarak Google API'lerini çağırmak için erişim jetonunu kullanın:
- Yeni bir
Google\Client
nesnesine erişim jetonu uygulamanız gerekiyorsa (ör. erişim jetonunu bir kullanıcı oturumunda depoladıysanız)setAccessToken
yöntemini kullanın:$client->setAccessToken($access_token);
- Çağırmak istediğiniz API için bir hizmet nesnesi oluşturun. Çağırmak istediğiniz API'nin oluşturucusuna yetkili bir
Google\Client
nesnesi sağlayarak bir hizmet nesnesi oluşturursunuz. Örneğin, Drive API'yi çağırmak için:$drive = new Google\Service\Drive($client);
-
Hizmet nesnesi tarafından sağlanan arayüzü kullanarak API hizmetine istek gönderin.
Örneğin, kimliği doğrulanmış kullanıcının Google Drive'ındaki dosyaları listelemek için:
$files = $drive->files->listFiles(array());
Python
Uygulamanız, erişim jetonu aldıktan sonra bu jetonu kullanarak belirli bir kullanıcı hesabı veya hizmet hesabı adına API isteklerini yetkilendirebilir. Çağırmak istediğiniz API için bir hizmet nesnesi oluşturmak üzere kullanıcıya özgü yetkilendirme kimlik bilgilerini kullanın ve ardından bu nesneyi kullanarak yetkili API istekleri gönderin.
- Çağırmak istediğiniz API için bir hizmet nesnesi oluşturun.
googleapiclient.discovery
kitaplığınınbuild
yöntemini API'nin adı, sürümü ve kullanıcı kimlik bilgileriyle çağırarak bir hizmet nesnesi oluşturursunuz: Örneğin, Drive API'nin 3. sürümünü çağırmak için:from googleapiclient.discovery import build drive = build('drive', 'v2', credentials=credentials)
- Hizmet nesnesi tarafından sağlanan arayüzü kullanarak API hizmetine istek gönderin.
Örneğin, kimliği doğrulanmış kullanıcının Google Drive'ındaki dosyaları listelemek için:
files = drive.files().list().execute()
Ruby
Uygulamanız, erişim jetonu aldıktan sonra bu jetonu kullanarak belirli bir kullanıcı hesabı veya hizmet hesabı adına API istekleri gönderebilir. Çağırmak istediğiniz API için bir hizmet nesnesi oluşturmak üzere kullanıcıya özgü yetkilendirme kimlik bilgilerini kullanın ve ardından bu nesneyi kullanarak yetkili API istekleri gönderin.
- Çağırmak istediğiniz API için bir hizmet nesnesi oluşturun.
Örneğin, Drive API'nin 3. sürümünü çağırmak için:
drive = Google::Apis::DriveV3::DriveService.new
- Hizmette kimlik bilgilerini ayarlayın:
drive.authorization = credentials
- Hizmet nesnesi tarafından sağlanan arayüzü kullanarak API hizmetine istek gönderin.
Örneğin, kimliği doğrulanmış kullanıcının Google Drive'ındaki dosyaları listelemek için:
files = drive.list_files
Alternatif olarak, bir yönteme options
parametresi sağlayarak yöntem bazında yetkilendirme sağlanabilir:
files = drive.list_files(options: { authorization: credentials })
Node.js
Erişim jetonu aldıktan ve jetonu OAuth2
nesnesine ayarladıktan sonra, Google API'lerini çağırmak için nesneyi kullanın. Uygulamanız, belirli bir kullanıcı hesabı veya hizmet hesabı adına API isteklerine yetki vermek için bu jetonu kullanabilir. Çağırmak istediğiniz API için bir hizmet nesnesi oluşturun.
Örneğin, aşağıdaki kodda kullanıcının Drive'ındaki dosya adlarını listelemek için Google Drive API kullanılmaktadır.
const { google } = require('googleapis'); // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } });
HTTP/REST
Uygulamanız bir erişim jetonu aldıktan sonra, API tarafından istenen erişim kapsamları verilmişse belirli bir 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
Tam örnek
Aşağıdaki örnekte, kullanıcı kimliğini doğrulayıp uygulamanın kullanıcının Drive meta verilerine erişmesine izin verdikten sonra kullanıcının Google Drive'ındaki dosyaların JSON biçimli listesi yazdırılmaktadır.
PHP
Bu örneği çalıştırmak için:
- API Consolebölümünde, yerel makinenin URL'sini yönlendirme URL'leri listesine ekleyin. Örneğin,
http://localhost:8080
ekleyin. - Yeni bir dizin oluşturun ve bu dizine geçin. Örneğin:
mkdir ~/php-oauth2-example cd ~/php-oauth2-example
- Composer'ı kullanarak PHP için Google API istemci kitaplığını yükleyin:
composer require google/apiclient:^2.15.0
- Aşağıdaki içerikle
index.php
veoauth2callback.php
dosyalarını oluşturun. - Örneği PHP'nin yerleşik test web sunucusuyla çalıştırın:
php -S localhost:8080 ~/php-oauth2-example
index.php
<?php require_once __DIR__.'/vendor/autoload.php'; session_start(); $client = new Google\Client(); $client->setAuthConfig('client_secret.json'); // User granted permission as an access token is in the session. if (isset($_SESSION['access_token']) && $_SESSION['access_token']) { $client->setAccessToken($_SESSION['access_token']); // Check if user granted Drive permission if ($_SESSION['granted_scopes_dict']['Drive']) { echo "Drive feature is enabled."; echo "</br>"; $drive = new Drive($client); $files = array(); $response = $drive->files->listFiles(array()); foreach ($response->files as $file) { echo "File: " . $file->name . " (" . $file->id . ")"; echo "</br>"; } } else { echo "Drive feature is NOT enabled."; echo "</br>"; } // Check if user granted Calendar permission if ($_SESSION['granted_scopes_dict']['Calendar']) { echo "Calendar feature is enabled."; echo "</br>"; } else { echo "Calendar feature is NOT enabled."; echo "</br>"; } } else { // Redirect users to outh2call.php which redirects users to Google OAuth 2.0 $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); } ?>
oauth2callback.php
<?php require_once __DIR__.'/vendor/autoload.php'; session_start(); $client = new Google\Client(); // Required, call the setAuthConfig function to load authorization credentials from // client_secret.json file. $client->setAuthConfigFile('client_secret.json'); $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF']); // Required, to set the scope value, call the addScope function. $client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]); // Enable incremental authorization. Recommended as a best practice. $client->setIncludeGrantedScopes(true); // Recommended, offline access will give you both an access and refresh token so that // your app can refresh the access token without user interaction. $client->setAccessType("offline"); // Generate a URL for authorization as it doesn't contain code and error if (!isset($_GET['code']) && !isset($_GET['error'])) { // Generate and set state value $state = bin2hex(random_bytes(16)); $client->setState($state); $_SESSION['state'] = $state; // Generate a url that asks permissions. $auth_url = $client->createAuthUrl(); header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL)); } // User authorized the request and authorization code is returned to exchange access and // refresh tokens. if (isset($_GET['code'])) { // Check the state value if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) { die('State mismatch. Possible CSRF attack.'); } // Get access and refresh tokens (if access_type is offline) $token = $client->fetchAccessTokenWithAuthCode($_GET['code']); /** Save access and refresh token to the session variables. * ACTION ITEM: In a production app, you likely want to save the * refresh token in a secure persistent storage instead. */ $_SESSION['access_token'] = $token; $_SESSION['refresh_token'] = $client->getRefreshToken(); // Space-separated string of granted scopes if it exists, otherwise null. $granted_scopes = $client->getOAuth2Service()->getGrantedScope(); // Determine which scopes user granted and build a dictionary $granted_scopes_dict = [ 'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY), 'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY) ]; $_SESSION['granted_scopes_dict'] = $granted_scopes_dict; $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); } // An error response e.g. error=access_denied if (isset($_GET['error'])) { echo "Error: ". $_GET['error']; } ?>
Python
Bu örnekte Flask çerçevesi kullanılmaktadır. http://localhost:8080
adresinde, OAuth 2.0 akışını test etmenizi sağlayan bir web uygulaması çalışır. Bu URL'ye gittiğinizde beş bağlantı görürsünüz:
- Drive API'yi çağır: Bu bağlantı, kullanıcılar izin verdiyse örnek bir API isteğini yürütmeye çalışan bir sayfaya yönlendirir. Gerekirse yetkilendirme akışını başlatır. İşlem başarılı olursa sayfada API yanıtı gösterilir.
- Takvim API'sini çağıracak örnek sayfa: Bu bağlantı, kullanıcılar izin verirse örnek bir Takvim API isteği yürütmeye çalışan bir örnek sayfaya yönlendirir. Gerekirse yetkilendirme akışını başlatır. İşlem başarılı olursa sayfada API yanıtı gösterilir.
- Doğrulama akışını doğrudan test edin: Bu bağlantı, kullanıcıyı doğrulama akışı üzerinden göndermeye çalışan bir sayfaya yönlendirir. Uygulama, kullanıcı adına yetkili API istekleri göndermek için izin ister.
- Mevcut kimlik bilgilerini iptal et: Bu bağlantı, kullanıcının uygulamaya daha önce verdiği izinleri iptal eden bir sayfaya yönlendirir.
- Flask oturum kimlik bilgilerini temizle: Bu bağlantı, Flask oturumunda depolanan yetkilendirme kimlik bilgilerini temizler. Bu sayede, uygulamanıza izin vermiş bir kullanıcı yeni bir oturumda API isteği yürütmeye çalışırsa ne olacağını görebilirsiniz. Ayrıca, bir kullanıcı uygulamanıza verilen izinleri iptal etmişse ve uygulamanız yine de iptal edilmiş bir erişim jetonuyla bir isteği yetkilendirmeye çalıştıysa uygulamanızın alacağı API yanıtını görmenizi sağlar.
# -*- coding: utf-8 -*- import os import flask import requests import google.oauth2.credentials import google_auth_oauthlib.flow import googleapiclient.discovery # This variable specifies the name of a file that contains the OAuth 2.0 # information for this application, including its client_id and client_secret. CLIENT_SECRETS_FILE = "client_secret.json" # The OAuth 2.0 access scope allows for access to the # authenticated user's account and requires requests to use an SSL connection. SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/calendar.readonly'] API_SERVICE_NAME = 'drive' API_VERSION = 'v2' app = flask.Flask(__name__) # Note: A secret key is included in the sample so that it works. # If you use this code in your application, replace this with a truly secret # key. See https://flask.palletsprojects.com/quickstart/#sessions. app.secret_key = 'REPLACE ME - this value is here as a placeholder.' @app.route('/') def index(): return print_index_table() @app.route('/drive') def drive_api_request(): if 'credentials' not in flask.session: return flask.redirect('authorize') features = flask.session['features'] if features['drive']: # Load credentials from the session. credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) drive = googleapiclient.discovery.build( API_SERVICE_NAME, API_VERSION, credentials=credentials) files = drive.files().list().execute() # Save credentials back to session in case access token was refreshed. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. flask.session['credentials'] = credentials_to_dict(credentials) return flask.jsonify(**files) else: # User didn't authorize read-only Drive activity permission. # Update UX and application accordingly return '<p>Drive feature is not enabled.</p>' @app.route('/calendar') def calendar_api_request(): if 'credentials' not in flask.session: return flask.redirect('authorize') features = flask.session['features'] if features['calendar']: # User authorized Calendar read permission. # Calling the APIs, etc. return ('<p>User granted the Google Calendar read permission. '+ 'This sample code does not include code to call Calendar</p>') else: # User didn't authorize Calendar read permission. # Update UX and application accordingly return '<p>Calendar feature is not enabled.</p>' @app.route('/authorize') def authorize(): # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps. flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES) # The URI created here must exactly match one of the authorized redirect URIs # for the OAuth 2.0 client, which you configured in the API Console. If this # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch' # error. flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true') # Store the state so the callback can verify the auth server response. flask.session['state'] = state return flask.redirect(authorization_url) @app.route('/oauth2callback') def oauth2callback(): # Specify the state when creating the flow in the callback so that it can # verified in the authorization server response. state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES, state=state) flow.redirect_uri = flask.url_for('oauth2callback', _external=True) # Use the authorization server's response to fetch the OAuth 2.0 tokens. authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store credentials in the session. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. credentials = flow.credentials credentials = credentials_to_dict(credentials) flask.session['credentials'] = credentials # Check which scopes user granted features = check_granted_scopes(credentials) flask.session['features'] = features return flask.redirect('/') @app.route('/revoke') def revoke(): if 'credentials' not in flask.session: return ('You need to <a href="/authorize">authorize</a> before ' + 'testing the code to revoke credentials.') credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) revoke = requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'}) status_code = getattr(revoke, 'status_code') if status_code == 200: return('Credentials successfully revoked.' + print_index_table()) else: return('An error occurred.' + print_index_table()) @app.route('/clear') def clear_credentials(): if 'credentials' in flask.session: del flask.session['credentials'] return ('Credentials have been cleared.<br><br>' + print_index_table()) def credentials_to_dict(credentials): return {'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'granted_scopes': credentials.granted_scopes} def check_granted_scopes(credentials): features = {} if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']: features['drive'] = True else: features['drive'] = False if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']: features['calendar'] = True else: features['calendar'] = False return features def print_index_table(): return ('<table>' + '<tr><td><a href="/test">Test an API request</a></td>' + '<td>Submit an API request and see a formatted JSON response. ' + ' Go through the authorization flow if there are no stored ' + ' credentials for the user.</td></tr>' + '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' + '<td>Go directly to the authorization flow. If there are stored ' + ' credentials, you still might not be prompted to reauthorize ' + ' the application.</td></tr>' + '<tr><td><a href="/revoke">Revoke current credentials</a></td>' + '<td>Revoke the access token associated with the current user ' + ' session. After revoking credentials, if you go to the test ' + ' page, you should see an <code>invalid_grant</code> error.' + '</td></tr>' + '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' + '<td>Clear the access token currently stored in the user session. ' + ' After clearing the token, if you <a href="/test">test the ' + ' API request</a> again, you should go back to the auth flow.' + '</td></tr></table>') if __name__ == '__main__': # When running locally, disable OAuthlib's HTTPs verification. # ACTION ITEM for developers: # When running in production *do not* leave this option enabled. os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # This disables the requested scopes and granted scopes check. # If users only grant partial request, the warning would not be thrown. os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1' # Specify a hostname and port that are set as a valid redirect URI # for your API project in the Google API Console. app.run('localhost', 8080, debug=True)
Ruby
Bu örnekte Sinatra çerçevesi kullanılmaktadır.
require 'googleauth' require 'googleauth/web_user_authorizer' require 'googleauth/stores/redis_token_store' require 'google/apis/drive_v3' require 'google/apis/calendar_v3' require 'sinatra' configure do enable :sessions # Required, call the from_file method to retrieve the client ID from a # client_secret.json file. set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json') # Required, scope value # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar. scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY', 'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY'] # Required, Authorizers require a storage instance to manage long term persistence of # access and refresh tokens. set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) # Required, indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. set :callback_uri, '/oauth2callback' # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI # from the client_secret.json file. To get these credentials for your application, visit # https://console.cloud.google.com/apis/credentials. set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, callback_uri: settings.callback_uri) end get '/' do # NOTE: Assumes the user is already authenticated to the app user_id = request.session['user_id'] # Fetch stored credentials for the user from the given request session. # nil if none present credentials = settings.authorizer.get_credentials(user_id, request) if credentials.nil? # Generate a url that asks the user to authorize requested scope(s). # Then, redirect user to the url. redirect settings.authorizer.get_authorization_url(request: request) end # User authorized the request. Now, check which scopes were granted. if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY) # User authorized read-only Drive activity permission. # Example of using Google Drive API to list filenames in user's Drive. drive = Google::Apis::DriveV3::DriveService.new files = drive.list_files(options: { authorization: credentials }) "<pre>#{JSON.pretty_generate(files.to_h)}</pre>" else # User didn't authorize read-only Drive activity permission. # Update UX and application accordingly end # Check if user authorized Calendar read permission. if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY) # User authorized Calendar read permission. # Calling the APIs, etc. else # User didn't authorize Calendar read permission. # Update UX and application accordingly end end # Receive the callback from Google's OAuth 2.0 server. get '/oauth2callback' do # Handle the result of the oauth callback. Defers the exchange of the code by # temporarily stashing the results in the user's session. target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url end
Node.js
Bu örneği çalıştırmak için:
-
API Consolebölümünde, yerel makinenin URL'sini yönlendirme URL'leri listesine ekleyin. Örneğin,
http://localhost
değerini ekleyin. - Bakım LTS, etkin LTS veya Node.js'in mevcut sürümünü yüklediğinizden emin olun.
-
Yeni bir dizin oluşturun ve bu dizine geçin. Örneğin:
mkdir ~/nodejs-oauth2-example cd ~/nodejs-oauth2-example
-
Install the
Google API Client
Library
for Node.js using npm:
npm install googleapis
-
Aşağıdaki içeriğe sahip
main.js
dosyalarını oluşturun. -
Örneği çalıştırın:
node .\main.js
main.js
const http = require('http'); const https = require('https'); const url = require('url'); const { google } = require('googleapis'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI. * To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/calendar.readonly' ]; /* Global variable that stores user credential in this code example. * ACTION ITEM for developers: * Store user's refresh token in your data store if * incorporating this code into your real app. * For more information on handling refresh tokens, * see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens */ let userCredential = null; async function main() { const app = express(); app.use(session({ secret: 'your_secure_secret_key', // Replace with a strong secret resave: false, saveUninitialized: false, })); // Example on redirecting user to Google's OAuth 2.0 server. app.get('/', async (req, res) => { // Generate a secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // Generate a url that asks permissions for the Drive activity and Google Calendar scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true, // Include the state parameter to reduce the risk of CSRF attacks. state: state }); res.redirect(authorizationUrl); }); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { // Handle the OAuth 2.0 server response let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); /** Save credential to the global variable in case access token was refreshed. * ACTION ITEM: In a production app, you likely want to save the refresh token * in a secure persistent database instead. */ userCredential = tokens; // User authorized the request. Now, check which scopes were granted. if (tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly')) { // User authorized read-only Drive activity permission. // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } }); } else { // User didn't authorize read-only Drive activity permission. // Update UX and application accordingly } // Check if user authorized Calendar read permission. if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly')) { // User authorized Calendar read permission. // Calling the APIs, etc. } else { // User didn't authorize Calendar read permission. // Update UX and application accordingly } } }); // Example on revoking a token app.get('/revoke', async (req, res) => { // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end(); }); const server = http.createServer(app); server.listen(8080); } main().catch(console.error);
HTTP/REST
Bu Python örneğinde, OAuth 2.0 web akışını göstermek için Flask çerçevesi ve Requests kitaplığı kullanılmaktadır. Bu akış için Python için Google API İstemci Kitaplığı'nı kullanmanızı öneririz. (Python sekmesindeki örnekte istemci kitaplığı kullanılmaktadır.)
import json import flask import requests app = flask.Flask(__name__) # To get these credentials (CLIENT_ID CLIENT_SECRET) and for your application, visit # https://console.cloud.google.com/apis/credentials. CLIENT_ID = '123456789.apps.googleusercontent.com' CLIENT_SECRET = 'abc123' # Read from a file or environmental variable in a real app # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar. SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly' # Indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. REDIRECT_URI = 'http://example.com/oauth2callback' @app.route('/') def index(): if 'credentials' not in flask.session: return flask.redirect(flask.url_for('oauth2callback')) credentials = json.loads(flask.session['credentials']) if credentials['expires_in'] <= 0: return flask.redirect(flask.url_for('oauth2callback')) else: # User authorized the request. Now, check which scopes were granted. if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['scope']: # User authorized read-only Drive activity permission. # Example of using Google Drive API to list filenames in user's Drive. headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])} req_uri = 'https://www.googleapis.com/drive/v2/files' r = requests.get(req_uri, headers=headers).text else: # User didn't authorize read-only Drive activity permission. # Update UX and application accordingly r = 'User did not authorize Drive permission.' # Check if user authorized Calendar read permission. if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['scope']: # User authorized Calendar read permission. # Calling the APIs, etc. r += 'User authorized Calendar permission.' else: # User didn't authorize Calendar read permission. # Update UX and application accordingly r += 'User did not authorize Calendar permission.' return r @app.route('/oauth2callback') def oauth2callback(): if 'code' not in flask.request.args: state = str(uuid.uuid4()) flask.session['state'] = state # Generate a url that asks permissions for the Drive activity # and Google Calendar scope. Then, redirect user to the url. auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code' '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI, SCOPE, state) return flask.redirect(auth_uri) else: if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']: return 'State mismatch. Possible CSRF attack.', 400 auth_code = flask.request.args.get('code') data = {'code': auth_code, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'redirect_uri': REDIRECT_URI, 'grant_type': 'authorization_code'} # Exchange authorization code for access and refresh tokens (if access_type is offline) r = requests.post('https://oauth2.googleapis.com/token', data=data) flask.session['credentials'] = r.text return flask.redirect(flask.url_for('index')) if __name__ == '__main__': import uuid app.secret_key = str(uuid.uuid4()) app.debug = False app.run()
Yönlendirme URI'si doğrulama kuralları
Google, geliştiricilerin uygulamalarının güvenliğini sağlamalarına yardımcı olmak için yönlendirme URI'lerine aşağıdaki doğrulama kurallarını uygular. Yönlendirme URI'leriniz bu kurallara uygun olmalıdır. Aşağıda bahsedilen alan, ana makine, yol, sorgu, şema ve userinfo tanımları için RFC 3986 bölüm 3'e bakın.
Doğrulama kuralları | |
---|---|
Şema |
Yönlendirme URI'leri, HTTP değil HTTPS şemasını kullanmalıdır. Yerel ana makine URI'leri (yerel ana makine IP adresi URI'leri dahil) bu kuraldan muaftır. |
Düzenleyen |
Ana makineler ham IP adresleri olamaz. Localhost IP adresleri bu kuraldan muaftır. |
Alan |
“googleusercontent.com” olamaz.goo.gl ) içeremez. Ayrıca, kısaltıcı alanına sahip bir uygulama bu alana yönlendirmeyi seçerse bu yönlendirme URI'si, yolunda “/google-callback/” içermeli veya “/google-callback” ile bitmelidir. |
Userinfo |
Yönlendirme URI'leri userinfo alt bileşenini içeremez. |
Yol |
Yönlendirme URI'leri, |
Sorgu |
Yönlendirme URI'leri açık yönlendirmeler içeremez. |
Fragment |
Yönlendirme URI'leri, parça bileşenini içeremez. |
Karakterler |
Yönlendirme URI'leri aşağıdakiler dahil belirli karakterler içeremez:
|
Artımlı yetkilendirme
OAuth 2.0 protokolünde uygulamanız, kapsamlarla tanımlanan kaynaklara erişmek için yetkilendirme ister. Kaynaklar için yetkilendirmeyi ihtiyaç duyduğunuz anda istemek, en iyi kullanıcı deneyimi uygulamalarından biri olarak kabul edilir. Bu uygulamayı etkinleştirmek için Google'ın yetkilendirme sunucusu artan yetkilendirmeyi destekler. Bu özellik, ihtiyaç duyduğunuz kapsamları istemenize olanak tanır ve kullanıcı yeni kapsam için izin verirse kullanıcının projeye verdiği tüm kapsamları içeren bir jetonla değiştirilebilecek bir yetkilendirme kodu döndürür.
Örneğin, kullanıcıların müzik parçalarından kesit almasına ve remiks oluşturmasına olanak tanıyan bir uygulamanın oturum açma sırasında çok az kaynağa (belki de oturum açan kişinin adından başka bir şeye) ihtiyacı olabilir. Ancak, tamamlanmış bir miksi kaydetmek için Google Drive'a erişmesi gerekir. Çoğu kullanıcı, Google Drive'larına yalnızca uygulamanın gerçekten ihtiyaç duyduğu sırada erişim izni verilmesini doğal karşılar.
Bu durumda, uygulama oturum açma sırasında temel oturum açmak için openid
ve profile
kapsamlarını isteyebilir, ardından bir miksaj kaydetmek için ilk istek sırasında https://www.googleapis.com/auth/drive.file
kapsamını isteyebilir.
Artımlı yetkilendirmeyi uygulamak için erişim jetonu istemeyle ilgili normal akışı tamamlarsınız ancak yetkilendirme isteğinin daha önce verilmiş kapsamları içerdiğinden emin olursunuz. Bu yaklaşım, uygulamanızın birden fazla erişim jetonu yönetmek zorunda kalmasını önler.
Artımlı yetkilendirmeden elde edilen erişim jetonları için aşağıdaki kurallar geçerlidir:
- Jeton, yeni, birleştirilmiş yetkilendirmeye dahil edilen kapsamlardan herhangi birine karşılık gelen kaynaklara erişmek için kullanılabilir.
- Erişim jetonu almak için birleştirilmiş yetkilendirme için yenileme jetonunu kullandığınızda erişim jetonu, birleştirilmiş yetkilendirmeyi temsil eder ve yanıtta yer alan
scope
değerlerinden herhangi biri için kullanılabilir. - Birleştirilmiş yetkilendirme, kullanıcının API projesine verdiği tüm kapsamları içerir. Bu kapsamlar farklı istemcilerden istenmiş olsa bile geçerlidir. Örneğin, bir kullanıcı bir uygulamanın masaüstü istemcisini kullanarak bir kapsama erişim izni verdiyse ve ardından mobil istemci aracılığıyla aynı uygulamaya başka bir kapsam için erişim izni verdiyse birleştirilmiş yetkilendirme her iki kapsamı da içerir.
- Birleştirilmiş yetkilendirmeyi temsil eden bir jetonu iptal ederseniz ilişkili kullanıcı adına bu yetkilendirmenin tüm kapsamlarına erişim de aynı anda iptal edilir.
1. Adım: Yetkilendirme parametrelerini ayarlama bölümündeki dile özgü kod örnekleri ve 2. Adım: Google'ın OAuth 2.0 sunucusuna yönlendirme bölümündeki örnek HTTP/REST yönlendirme URL'si, artımlı yetkilendirmeyi kullanır. Aşağıdaki kod örneklerinde, artımlı yetkilendirmeyi kullanmak için eklemeniz gereken kod da gösterilmektedir.
PHP
$client->setIncludeGrantedScopes(true);
Python
Python'da, bir yetkilendirme isteğinin daha önce verilmiş kapsamları içerdiğinden emin olmak için include_granted_scopes
anahtar kelime bağımsız değişkenini true
olarak ayarlayın. Aşağıdaki örnekte gösterildiği gibi, include_granted_scopes
'ün, ayarladığınız tek anahtar kelime bağımsız değişkeni olmaması olasıdır.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
Ruby
auth_client.update!( :additional_parameters => {"include_granted_scopes" => "true"} )
Node.js
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
HTTP/REST
GET https://accounts.google.com/o/oauth2/v2/auth? client_id=your_client_id& response_type=code& state=state_parameter_passthrough_value& scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly& redirect_uri=https%3A//oauth2.example.com/code& prompt=consent& include_granted_scopes=true
Erişim jetonunu yenileme (çevrimdışı erişim)
Erişim jetonlarının süresi düzenli olarak dolar ve ilgili API isteği için geçersiz kimlik bilgileri haline gelir. Jetonla ilişkili kapsamlara çevrimdışı erişim isteğinde bulunduysanız kullanıcıdan izin istemeden (kullanıcı mevcut olmadığında dahil) bir erişim jetonunu yenileyebilirsiniz.
- Google API istemci kitaplığı kullanıyorsanız istemci nesnesi, bu nesneyi çevrimdışı erişim için yapılandırdığınız sürece erişim jetonunu gerektiği gibi yeniler.
- İstemci kitaplığı kullanmıyorsanız kullanıcıyı Google'ın OAuth 2.0 sunucusuna yönlendirirken
access_type
HTTP sorgu parametresinioffline
olarak ayarlamanız gerekir. Bu durumda, Google'ın yetkilendirme sunucusu, erişim jetonu için yetkilendirme kodu değiş tokuşu yaptığınızda yenileme jetonu döndürür. Ardından, erişim jetonunun süresi dolduğunda (veya başka bir zamanda) yeni bir erişim jetonu almak için yenileme jetonunu kullanabilirsiniz.
Çevrimdışı erişim isteğinde bulunma, kullanıcı mevcut olmadığında bir Google API'sine erişmesi gereken tüm uygulamalar için zorunludur. Örneğin, yedekleme hizmetleri yürüten veya önceden belirlenmiş zamanlarda işlem yapan bir uygulamanın, kullanıcı mevcut olmadığında erişim jetonunu yenilemesi gerekir. Varsayılan erişim stilinin adı online
.
Sunucu tarafı web uygulamaları, yüklü uygulamalar ve cihazların tümü yetkilendirme işlemi sırasında yenileme jetonu alır. Yenileme jetonları genellikle istemci tarafı (JavaScript) web uygulamalarında kullanılmaz.
PHP
Uygulamanızın bir Google API'sine çevrimdışı erişmesi gerekiyorsa API istemcisinin erişim türünü offline
olarak ayarlayın:
$client->setAccessType("offline");
Kullanıcı, istenen kapsamlara çevrimdışı erişim izni verdikten sonra, kullanıcı çevrimdışıyken kullanıcı adına Google API'lerine erişmek için API istemcisini kullanmaya devam edebilirsiniz. İstemci nesnesi, erişim jetonunu gerektiğinde yeniler.
Python
Python'da, kullanıcıdan izin istemek zorunda kalmadan erişim jetonunu yenileyebilmeniz için access_type
anahtar kelime bağımsız değişkenini offline
olarak ayarlayın. Aşağıdaki örnekte gösterildiği gibi, access_type
'ün, ayarladığınız tek anahtar kelime bağımsız değişkeni olmaması olasıdır.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
Kullanıcı, istenen kapsamlara çevrimdışı erişim izni verdikten sonra, kullanıcı çevrimdışıyken kullanıcı adına Google API'lerine erişmek için API istemcisini kullanmaya devam edebilirsiniz. İstemci nesnesi, erişim jetonunu gerektiğinde yeniler.
Ruby
Uygulamanızın bir Google API'sine çevrimdışı erişmesi gerekiyorsa API istemcisinin erişim türünü offline
olarak ayarlayın:
auth_client.update!( :additional_parameters => {"access_type" => "offline"} )
Kullanıcı, istenen kapsamlara çevrimdışı erişim izni verdikten sonra, kullanıcı çevrimdışıyken kullanıcı adına Google API'lerine erişmek için API istemcisini kullanmaya devam edebilirsiniz. İstemci nesnesi, erişim jetonunu gerektiğinde yeniler.
Node.js
Uygulamanızın bir Google API'sine çevrimdışı erişmesi gerekiyorsa API istemcisinin erişim türünü offline
olarak ayarlayın:
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
Kullanıcı, istenen kapsamlara çevrimdışı erişim izni verdikten sonra, kullanıcı çevrimdışıyken kullanıcı adına Google API'lerine erişmek için API istemcisini kullanmaya devam edebilirsiniz. İstemci nesnesi, erişim jetonunu gerektiğinde yeniler.
Erişim jetonlarının süresi dolar. Bu kitaplık, süresi dolmak üzere olan yeni bir erişim jetonu almak için otomatik olarak yenileme jetonu kullanır. Her zaman en son jetonları depoladığınızdan emin olmanın kolay bir yolu, jetonlar etkinliğini kullanmaktır:
oauth2Client.on('tokens', (tokens) => { if (tokens.refresh_token) { // store the refresh_token in your secure persistent database console.log(tokens.refresh_token); } console.log(tokens.access_token); });
Bu jeton etkinliği yalnızca ilk yetkilendirmede gerçekleşir ve yenileme jetonunu almak için generateAuthUrl
yöntemini çağırırken access_type
değerini offline
olarak ayarlamanız gerekir. Yenileme jetonu almak için gerekli kısıtlamaları belirlemeden uygulamanıza gerekli izinleri zaten verdiyseniz yeni bir yenileme jetonu almak için uygulamayı yeniden yetkilendirmeniz gerekir.
refresh_token
değerini daha sonra ayarlamak için setCredentials
yöntemini kullanabilirsiniz:
oauth2Client.setCredentials({ refresh_token: `STORED_REFRESH_TOKEN` });
İstemcinin yenileme jetonu olduğunda, erişim jetonları API'ye yapılan bir sonraki çağrıda otomatik olarak alınır ve yenilenir.
HTTP/REST
Uygulamanız, bir erişim jetonunu yenilemek için Google'ın yetkilendirme sunucusuna (https://oauth2.googleapis.com/token
) aşağıdaki parametreleri içeren bir HTTPS POST
isteğinde bulunur:
Alanlar | |
---|---|
client_id |
API Consolekaynağından alınan istemci kimliği. |
client_secret |
API Consolekaynağından alınan istemci gizli anahtarı. |
grant_type |
OAuth 2.0 spesifikasyonunda tanımlandığı gibi, bu alanın değeri refresh_token olarak ayarlanmalıdır. |
refresh_token |
Yetkilendirme kodu değişiminden döndürülen yenileme jetonu. |
Aşağıdaki snippet'te örnek bir istek gösterilmektedir:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=your_client_id& client_secret=your_client_secret& refresh_token=refresh_token& grant_type=refresh_token
Kullanıcı, uygulamaya verilen erişimi iptal etmediği sürece jeton sunucusu yeni bir erişim jetonu içeren bir JSON nesnesi döndürür. Aşağıdaki snippet'te örnek bir yanıt gösterilmektedir:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly", "token_type": "Bearer" }
Verilecek yenileme jetonu sayısıyla ilgili sınırlamalar olduğunu unutmayın. Bu sınırlamalar, istemci/kullanıcı kombinasyonu başına bir tane ve tüm istemciler genelinde kullanıcı başına bir tanedir. Yenileme jetonlarını uzun süreli depolama alanına kaydetmeniz ve geçerli oldukları sürece kullanmaya devam etmeniz gerekir. Uygulamanız çok fazla yenileme jetonu isterse bu sınırlara ulaşabilir. Bu durumda eski yenileme jetonları çalışmayı durdurur.
Jetonu iptal etme
Bazı durumlarda kullanıcılar, bir uygulamaya verilen erişimi iptal etmek isteyebilir. Kullanıcılar Hesap Ayarları'nı ziyaret ederek erişimi iptal edebilir. Daha fazla bilgi için Hesabınıza erişimi olan üçüncü taraf site ve uygulamaların Site veya uygulama erişimini kaldırma bölümünü inceleyin.
Bir uygulamanın kendisine verilen erişimi programatik olarak iptal etmesi de mümkündür. Programatik iptal, kullanıcının aboneliğini iptal ettiği, bir uygulamayı kaldırdığı veya bir uygulamanın ihtiyaç duyduğu API kaynaklarının önemli ölçüde değiştiği durumlarda önemlidir. Diğer bir deyişle, kaldırma işleminin bir kısmı, daha önce uygulamaya verilen izinlerin kaldırılmasını sağlamak için bir API isteği içerebilir.
PHP
Bir jetonu programatik olarak iptal etmek için revokeToken()
işlevini çağırın:
$client->revokeToken();
Python
Bir jetonu programatik olarak iptal etmek için https://oauth2.googleapis.com/revoke
adresine, jetonu parametre olarak içeren ve Content-Type
üstbilgisini ayarlayan bir istek gönderin:
requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'})
Ruby
Bir jetonu programatik olarak iptal etmek için oauth2.revoke
uç noktasına bir HTTP isteği gönderin:
uri = URI('https://oauth2.googleapis.com/revoke') response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
Jeton, erişim jetonu veya yenileme jetonu olabilir. Jeton bir erişim jetonuysa ve ilgili bir yenileme jetonu varsa yenileme jetonu da iptal edilir.
İptal işlemi başarıyla işlenirse yanıtın durum kodu 200
olur. Hata durumlarında, hata koduyla birlikte bir durum kodu 400
döndürülür.
Node.js
Bir jetonu programatik olarak iptal etmek için /revoke
ucuna HTTPS POST isteği gönderin:
const https = require('https'); // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end();
Jeton parametresi bir erişim jetonu veya yenileme jetonu olabilir. Jeton bir erişim jetonuysa ve ilgili bir yenileme jetonu varsa yenileme jetonu da iptal edilir.
İptal işlemi başarıyla işlenirse yanıtın durum kodu 200
olur. Hata durumlarında, hata koduyla birlikte bir durum kodu 400
döndürülür.
HTTP/REST
Bir jetonu programatik olarak iptal etmek için uygulamanız https://oauth2.googleapis.com/revoke
adresine bir istek gönderir ve jetonu parametre olarak ekler:
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token={token}
Jeton, erişim jetonu veya yenileme jetonu olabilir. Jeton bir erişim jetonuysa ve buna karşılık gelen bir yenileme jetonu varsa yenileme jetonu da iptal edilir.
İptal işlemi başarıyla işlenirse yanıtın HTTP durum kodu 200
olur. Hata durumlarında, hata koduyla birlikte bir HTTP durum kodu 400
döndürülür.
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.