OAuth 2.0'ı Java için Google API İstemci Kitaplığı ile Kullanma

Genel Bakış

Amaç: Bu belgede, Google hizmetleriyle OAuth 2.0 yetkilendirmesi yapmak için GoogleCredential yardımcı sınıfının nasıl kullanılacağı açıklanmaktadır. Sağladığımız genel OAuth 2.0 işlevleri hakkında bilgi için OAuth 2.0 ve Java için Google OAuth İstemci Kitaplığı başlıklı makaleyi inceleyin.

Özet: Google hizmetlerinde depolanan korumalı verilere erişmek için yetkilendirme amacıyla OAuth 2.0'ı kullanın. Google API'leri, farklı istemci uygulaması türleri için OAuth 2.0 akışlarını destekler. Bu akışların tümünde, istemci uygulaması yalnızca istemci uygulamanızla ve erişilen korumalı verilerin sahibiyle ilişkilendirilmiş bir erişim jetonu ister. Erişim jetonu, istemci uygulamanızın erişebileceği veri türünü tanımlayan sınırlı bir kapsamla da ilişkilendirilir (örneğin, "Görevlerinizi yönetin"). OAuth 2.0'ın önemli bir hedefi, erişim jetonu çalınması durumunda olası etkiyi en aza indirirken korunan verilere güvenli ve kolay erişim sağlamaktır.

Java için Google API İstemci Kitaplığı'ndaki OAuth 2.0 paketleri, genel amaçlı Java için Google OAuth 2.0 İstemci Kitaplığı üzerine kurulmuştur.

Ayrıntılar için aşağıdaki paketlerin Javadoc belgelerine bakın:

Google API Konsolu

Google API'lerine erişebilmeniz için, istemciniz yüklü bir uygulama, mobil uygulama, web sunucusu veya tarayıcıda çalışan bir istemci olsa da kimlik doğrulama ve faturalandırma amacıyla Google API Konsolu'nda bir proje oluşturmanız gerekir.

Kimlik bilgilerinizi doğru şekilde ayarlama talimatları için API Konsolu Yardım Merkezi'ne bakın.

Kimlik bilgisi

GoogleCredential

GoogleCredential, erişim jetonu kullanılarak korunan kaynaklara erişmek için OAuth 2.0'ın iş parçacığı açısından güvenli yardımcı sınıfıdır. Örneğin, zaten bir erişim jetonunuz varsa aşağıdaki şekilde istekte bulunabilirsiniz:

GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
Plus plus = new Plus.builder(new NetHttpTransport(),
                             GsonFactory.getDefaultInstance(),
                             credential)
    .setApplicationName("Google-PlusSample/1.0")
    .build();

Google App Engine kimliği

Bu alternatif kimlik bilgisi, Google App Engine App Identity Java API'ye dayanır. Bir istemci uygulamasının bir son kullanıcının verilerine erişim isteğinde bulunduğu kimlik bilgilerinin aksine, App Identity API, istemci uygulamasının kendi verilerine erişim sağlar.

AppIdentityCredential'ı kullanın (google-api-client-appengine'den). Google App Engine tüm ayrıntılarla ilgilendiği için bu kimlik bilgisi çok daha basittir. Yalnızca ihtiyacınız olan OAuth 2.0 kapsamını belirtirsiniz.

urlshortener-robots-appengine-sample adresinden alınan örnek kod:

static Urlshortener newUrlshortener() {
  AppIdentityCredential credential =
      new AppIdentityCredential(
          Collections.singletonList(UrlshortenerScopes.URLSHORTENER));
  return new Urlshortener.Builder(new UrlFetchTransport(),
                                  GsonFactory.getDefaultInstance(),
                                  credential)
      .build();
}

Veri deposu

Erişim jetonunun geçerlilik süresi genellikle 1 saattir. Bu sürenin ardından jetonu kullanmaya çalıştığınızda hata alırsınız. GoogleCredential, jetonu otomatik olarak "yenileme" işlemini gerçekleştirir. Bu işlem, yeni bir erişim jetonu alma anlamına gelir. Bu işlem, yetkilendirme kodu akışı sırasında access_type=offline parametresini kullanırsanız genellikle erişim jetonuyla birlikte alınan uzun süreli bir yenileme jetonu aracılığıyla yapılır (bkz. GoogleAuthorizationCodeFlow.Builder.setAccessType(String)).

Çoğu uygulamanın kimlik bilgisinin erişim jetonunu ve/veya yenileme jetonunu kalıcı hale getirmesi gerekir. Kimliğin erişim ve/veya yenileme jetonlarını kalıcı hale getirmek için DataStoreFactory'nin kendi uygulamanızı StoredCredential ile sağlayabilir veya kitaplık tarafından sağlanan aşağıdaki uygulamalardan birini kullanabilirsiniz:

  • AppEngineDataStoreFactory: Google App Engine Data Store API'yi kullanarak kimlik bilgisini kalıcı hale getirir.
  • MemoryDataStoreFactory: Kimliği bellekte "kalıcı hale getirir". Bu yalnızca işlemin ömrü boyunca kısa süreli depolama alanı olarak kullanışlıdır.
  • FileDataStoreFactory: Kimlik bilgisini bir dosyada kalıcı hale getirir.

App Engine kullanıcıları: AppEngineCredentialStore desteği sonlandırıldı ve yakında kaldırılacak. StoredCredential ile AppEngineDataStoreFactory'yi kullanmanızı öneririz. Kimlik bilgileriniz eski yöntemle depolanıyorsa geçişi yapmak için eklenen yardımcı yöntemler migrateTo(AppEngineDataStoreFactory) veya migrateTo(DataStore)'u kullanabilirsiniz.

DataStoreCredentialRefreshListener'ı kullanabilir ve GoogleCredential.Builder.addRefreshListener(CredentialRefreshListener) kullanarak kimlik bilgisi için ayarlayabilirsiniz.

Yetkilendirme kodu akışı

Son kullanıcının, uygulamanıza Google API'lerindeki korumalı verilerine erişim izni vermesine olanak tanımak için yetkilendirme kodu akışını kullanın. Bu akışın protokolü, Authorization Code Grant'te (Yetkilendirme Kodu İzni) belirtilir.

Bu akış, GoogleAuthorizationCodeFlow kullanılarak uygulanır. Adımlar aşağıdaki gibidr:

  • Son kullanıcı uygulamanıza giriş yapar. Bu kullanıcıyı, uygulamanız için benzersiz olan bir kullanıcı kimliğiyle ilişkilendirmeniz gerekir.
  • Son kullanıcının kimlik bilgilerinin zaten bilindiğini kontrol etmek için kullanıcı kimliğine göre AuthorizationCodeFlow.loadCredential(String)) işlevini çağırın. Bu durumda işlem tamamlanır.
  • Aksi takdirde, AuthorizationCodeFlow.newAuthorizationUrl() işlevini çağırın ve son kullanıcının tarayıcısını, uygulamanıza korunmuş verilerine erişim izni vereceği bir yetkilendirme sayfasına yönlendirin.
  • Ardından Google yetkilendirme sunucusu, tarayıcıyı code sorgu parametresiyle birlikte uygulamanız tarafından belirtilen yönlendirme URL'sine geri yönlendirir. AuthorizationCodeFlow.newTokenRequest(String)) kullanarak erişim jetonu istemek için code parametresini kullanın.
  • Korunan kaynaklara erişmek için kimlik bilgisi depolamak ve almak üzere AuthorizationCodeFlow.createAndStoreCredential(TokenResponse, String)) yöntemini kullanın.

Alternatif olarak, GoogleAuthorizationCodeFlow kullanmıyorsanız daha düşük düzeydeki sınıfları kullanabilirsiniz:

Projenizi Google API Konsolu'nda ayarlarken kullandığınız akışa bağlı olarak farklı kimlik bilgileri arasından seçim yaparsınız. Daha fazla bilgi için OAuth 2.0'ı ayarlama ve OAuth 2.0 Senaryoları başlıklı makaleleri inceleyin. Her akışın kod snippet'lerini aşağıda bulabilirsiniz.

Web sunucusu uygulamaları

Bu akışın protokolü Web Sunucusu Uygulamaları için OAuth 2.0'ı Kullanma bölümünde açıklanmaktadır.

Bu kitaplık, temel kullanım alanları için yetkilendirme kodu akışını önemli ölçüde basitleştirmek üzere servlet yardımcı sınıfları sağlar. AbstractAuthorizationCodeServlet ve AbstractAuthorizationCodeCallbackServlet'in (google-oauth-client-servlet'ten) somut alt sınıflarını sağlamanız ve bunları web.xml dosyanıza eklemeniz yeterlidir. Web uygulamanız için kullanıcı girişini yönetmeniz ve kullanıcı kimliği çıkarmanız gerektiğini unutmayın.

public class CalendarServletSample extends AbstractAuthorizationCodeServlet {

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
    // do stuff
  }

  @Override
  protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
    GenericUrl url = new GenericUrl(req.getRequestURL().toString());
    url.setRawPath("/oauth2callback");
    return url.build();
  }

  @Override
  protected AuthorizationCodeFlow initializeFlow() throws IOException {
    return new GoogleAuthorizationCodeFlow.Builder(
        new NetHttpTransport(), GsonFactory.getDefaultInstance(),
        "[[ENTER YOUR CLIENT ID]]", "[[ENTER YOUR CLIENT SECRET]]",
        Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(
        DATA_STORE_FACTORY).setAccessType("offline").build();
  }

  @Override
  protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
    // return user ID
  }
}

public class CalendarServletCallbackSample extends AbstractAuthorizationCodeCallbackServlet {

  @Override
  protected void onSuccess(HttpServletRequest req, HttpServletResponse resp, Credential credential)
      throws ServletException, IOException {
    resp.sendRedirect("/");
  }

  @Override
  protected void onError(
      HttpServletRequest req, HttpServletResponse resp, AuthorizationCodeResponseUrl errorResponse)
      throws ServletException, IOException {
    // handle error
  }

  @Override
  protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
    GenericUrl url = new GenericUrl(req.getRequestURL().toString());
    url.setRawPath("/oauth2callback");
    return url.build();
  }

  @Override
  protected AuthorizationCodeFlow initializeFlow() throws IOException {
    return new GoogleAuthorizationCodeFlow.Builder(
        new NetHttpTransport(),