Genel Bakış
Amaç: Bu belgede, GoogleCredential yardımcı program sınıfı için Google hizmetleriyle OAuth 2.0 yetkilendirmesi gerçekleştirin. Örneğin, sağladığımız genel OAuth 2.0 işlevleri hakkında bilgi edinmek için OAuth 2.0 ve Java için Google OAuth İstemci Kitaplığı.
Özet: Google hizmetlerinde depolanan korunan verilere erişmek için Yetkilendirme için OAuth 2.0. Google API'leri farklı istemci uygulaması türleri için OAuth 2.0 akışlarını destekler. Tüm bu akışlarda istemci uygulaması şuna benzer bir erişim jetonu ister: yalnızca istemci uygulamanızla ve korunan verilerin sahibiyle ilişkili emin olun. Erişim jetonu ayrıca sınırlı bir kapsamla ilişkilendirilir. istemci uygulamanızın erişebildiği veri türünü tanımlar (örneğin "Görevlerinizi yönetin"). OAuth 2.0 için önemli bir hedef, koruma altındaki verilere kolay erişim ve olası etkiyi en aza indirir. ihlal anlamına gelir.
Java için Google API İstemci Kitaplığı'ndaki OAuth 2.0 paketleri, genel amaçlı Java için Google OAuth 2.0 istemci kitaplığı.
Ayrıntılı bilgi için aşağıdaki paketlere ilişkin Javadoc dokümanlarına bakın:
- com.google.api.client.googleapis.auth.oauth2 (google-api-client'den)
- com.google.api.client.googleapis.extensions.appengine.auth.oauth2 (google-api-client-appengine'den)
Google API Konsolu
Google API'lerine erişebilmeniz için şurada bir proje oluşturmanız gerekir: Kimlik doğrulama ve faturalandırma için Google API Konsolu ister yüklü bir uygulama, ister mobil bir uygulama, bir web sunucusu veya tarayıcıda çalışan bir istemci olabilir.
Kimlik bilgilerinizi düzgün şekilde ayarlamayla ilgili talimatlar için API Konsolu Yardımı.
Kimlik bilgisi
GoogleCredential
GoogleCredential korumalı kaynaklara erişim için OAuth 2.0 için iş parçacığı açısından güvenli bir yardımcı sınıftır erişim jetonundan yararlanabilirsiniz. Örneğin, zaten bir erişim jetonunuz varsa şu şekilde istekte bulunabilir:
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 yeterlilik belgesi, Google App Engine App Identity Java API. İstemci uygulamasının bir App Identity API, son kullanıcı tarafından kullanılan istemciye uygulamanızın kendi verilerini oluşturun.
AppIdentityCredential'ı kullanın. (google-api-client-appengine'den). Google App Engine tüm bu işlemleri gerçekleştirdiğinden, bu kimlik bilgisi çok daha basittir gösterir. Yalnızca ihtiyacınız olan OAuth 2.0 kapsamını belirtin.
urlshortener-robots-appengine-sample parametresinden 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 bitiş tarihi genellikle 1 saattir ve bu tarihten sonra
kullanmaya çalışırsanız hata alırsınız.
GoogleCredential
otomatik olarak "yenileme" işlemini Bu da yeni web sitesi oluşturmak için
yeni bir erişim jetonu ekleyebilirsiniz. Bu, uzun ömürlü bir yenileme jetonuyla yapılır ve
Yetkilendirme kodu akışı sırasında access_type=offline
parametresi (
GoogleAuthorizationCodeFlow.Builder.setAccessType(String).
Çoğu uygulamanın, kimlik bilgisinin erişim jetonunu ve/veya yenileme jetonuna dokunun. Kimlik bilgilerinin erişimini ve/veya yenileme jetonlarını sürdürmek için Kendi DataStoreFactory uygulamanızı sağlayabilirsiniz StoredCredential ile veya kitaplık tarafından sağlanan aşağıdaki uygulamalardan birini kullanabilirsiniz:
- AppEngineDataStoreFactory: Google App Engine Data Store API'yi kullanarak kimlik bilgisini güncel tutmalıdır.
- MemoryDataStoreFactory: "kalıcı" Bu bilgi, sürecin ömrü boyunca yalnızca kısa süreli depolama olarak kullanışlıdır.
- FileDataStoreFactory: kimlik bilgisini bir dosyada tutar.
AppEngine Kullanıcıları: AppEngineCredentialStore desteği sonlandırıldı ve yakında kaldırılacak. Optimum kampanya performansı için AppEngineDataStoreFactory StoredCredential ile kullanın. Eski yöntemlerle depolanmış kimlik bilgileriniz varsa eklenen yardımcı yöntemler migrateTo(AppEngineDataStoreFactory) veya migrateTo(DataStore) gerçekleştirebilirler.
Şunları kullanabilirsiniz: DataStoreCredentialRefreshListener ve GoogleCredential.Builder.addRefreshListener(CredentialRefreshListener) kullanarak kimlik bilgisi için ayarlayın.
Yetkilendirme kodu akışı
Son kullanıcının uygulamanıza izin vermesi için yetkilendirme kodu akışını kullanın Google API'lerinde korunan verilerine erişmelerine yardımcı olun. Bu akışa ilişkin protokol belirtilen Yetkilendirme Kodu Verme.
Bu akış, GoogleAuthorizationCodeFlow kullanılarak uygulanır. Adımlar aşağıdaki gibidr:
- Son kullanıcı, uygulamanıza giriş yapar. Bu kullanıcıyı ilişkilendirmeniz gerekir benzersiz bir kullanıcı kimliği kullanın.
- AuthorizationCodeFlow.loadCredential(String) çağrısı yapın kullanıcı kimliğini temel alır. Öyleyse işimiz bitti demektir.
- Aksi halde AuthorizationCodeFlow.newAuthorizationUrl() çağrısını yapın ve son kullanıcının tarayıcısını, web sitenizin yeni sürümüne izin vermek için erişimine açık olacak.
- Ardından, Google yetkilendirme sunucusu, tarayıcıyı tekrar
code
sorgusuyla birlikte uygulamanız tarafından belirtilen yönlendirme URL'si parametresinden sonra bir değer girin. Erişim jetonu istemek için şunu kullanarakcode
parametresini kullanın: AuthorizationCodeFlow.newTokenRequest(String): - AuthorizationCodeFlow.createAndStoreCredential(TokenResponse, String) ifadesini kullanın. (korunan kaynaklara erişmek için kimlik bilgisi depolamak ve almak için)
GoogleAuthorizationCodeFlow kullanmıyorsanız daha alt düzey sınıfları da kullanabilirsiniz:
- Kullanıcı kimliğine göre mağazadan kimlik bilgisini yüklemek için DataStore.get(String) işlevini kullanın.
- Tarayıcıyı yetkilendirme sayfasına yönlendirmek için GoogleAuthorizationCodeRequestUrl'yi kullanın.
- Yetkilendirme yanıtını işlemek ve yetkilendirme kodunu ayrıştırmak için AuthorizationCodeResponseUrl'yi kullanın.
- Erişim jetonu ve muhtemelen bir yenileme jetonu istemek için GoogleAuthorizationCodeTokenRequest'i kullanın.
- Yeni bir GoogleCredential oluşturun ve bunu DataStore.set(String, V) kullanarak depolayın.
GoogleCredential
kullanarak korunan kaynaklara erişin. Süresi dolan erişim jetonları, yenileme jetonuyla (varsa) otomatik olarak yenilenir. DataStoreCredentialRefreshListener'ı kullandığınızdan ve bunu GoogleCredential.Builder.addRefreshListener(CredentialRefreshListener) yoluyla kimlik bilgisi için ayarladığınızdan emin olun.
Projenizi Google API Konsolu'nda oluşturduğunuzda, kullandığınız akışa bağlı olarak farklı kimlik bilgileri arasından seçim yapabilirsiniz. Daha fazla bilgi için OAuth 2.0'ı kurma başlıklı makaleye göz atın. ve OAuth 2.0 Senaryoları hakkında daha fazla bilgi edinin. Her bir akışa ait kod snippet'leri aşağıda verilmiştir.
Web sunucusu uygulamaları
Bu akışa ilişkin protokol şurada açıklanmıştır: Web Sunucusu Uygulamaları için OAuth 2.0'ı Kullanma.
Bu kitaplık, performansı önemli ölçüde basitleştirmek için servlet yardımcı sınıfları yetkilendirme kodu akışını izleyin. Yalnızca somut alt sınıflar sağlarsınız AbstractAuthorizationCodeServlet listesi ve AbstractAuthorizationCodeCallbackServlet (google-oauth-client-servlet'ten) ve web.xml dosyanıza ekleyin. Kullanıcıyla yine de ilgilenmeniz gerektiğini unutmayın. web uygulamanız için giriş yapın ve bir kullanıcı kimliği çıkarı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(), 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 } }
Google App Engine uygulamaları
App Engine'deki yetkilendirme kodu akışı servlet ile neredeyse aynıdır yetkilendirme kodu akışını, yalnızca Google App Engine'in Kullanıcılar Java API'si. Kullanıcı Users Java API'nin etkinleştirilmesi için giriş yapılması gerekir; şunun hakkında bilgi için: kullanıcıları bir giriş sayfasına yönlendirirse, bu bilgilere göz atın. Güvenlik ve Kimlik Doğrulama (web.xml dosyasında).
servlet durumundan ilk fark, somut bir ortam sağlayarak
alt sınıfları
AbstractAppEngineAuthorizationCodeServlet ve AbstractAppEngineAuthorizationCodeCallbackServlet
(google-oauth-client-appengine'den.
Soyut servlet sınıflarını genişletir ve getUserId
yöntemini uygularlar
sizin için en uygun platformdur. AppEngineDataStoreFactory
(google-http-client-appengine'den)
Google App Engine Verilerini kullanarak kimlik bilgisini kalıcı hale getirmek için iyi bir seçenektir
Store API'si.
calendar-appengine-sample'dan alınmış (biraz değiştirilmiş):
public class CalendarAppEngineSample extends AbstractAppEngineAuthorizationCodeServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // do stuff } @Override protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException { return Utils.getRedirectUri(req); } @Override protected AuthorizationCodeFlow initializeFlow() throws IOException { return Utils.newFlow(); } } class Utils { static String getRedirectUri(HttpServletRequest req) { GenericUrl url = new GenericUrl(req.getRequestURL().toString()); url.setRawPath("/oauth2callback"); return url.build(); } static GoogleAuthorizationCodeFlow newFlow() throws IOException { return new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, getClientCredential(), Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory( DATA_STORE_FACTORY).setAccessType("offline").build(); } } public class OAuth2Callback extends AbstractAppEngineAuthorizationCodeCallbackServlet { private static final long serialVersionUID = 1L; @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 { String nickname = UserServiceFactory.getUserService().getCurrentUser().getNickname(); resp.getWriter().print("<h3>" + nickname + ", why don't you want to play with me?</h1>"); resp.setStatus(200); resp.addHeader("Content-Type", "text/html"); } @Override protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException { return Utils.getRedirectUri(req); } @Override protected AuthorizationCodeFlow initializeFlow() throws IOException { return Utils.newFlow(); } }
Daha fazla örnek için bkz. storage-serviceaccount-appengine-sample.
Hizmet hesapları
GoogleCredential hizmet hesaplarını da destekler. İstemci uygulamasının bir yardımcı olmak için, Hizmet Hesapları istemci uygulamasının sahip olmanız gerekir. İstemci uygulamanız, erişim jetonu isteğini Google API Konsolu'ndan indirilen bir özel anahtar.
plus-serviceaccount-cmdline-sample'dan alınan örnek kod:
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); JsonFactory jsonFactory = GsonFactory.getDefaultInstance(); ... // Build service account credential. GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json")) .createScoped(Collections.singleton(PlusScopes.PLUS_ME)); // Set up global Plus instance. plus = new Plus.Builder(httpTransport, jsonFactory, credential) .setApplicationName(APPLICATION_NAME).build(); ...
Daha fazla örnek için bkz. storage-serviceaccount-cmdline-sample.
Kimliğe Bürünme
Aynı zamanda hizmet hesabı akışını, aynı alan adındaki bir kullanıcının kimliğine bürünmek için de kullanabilirsiniz. sahip olmanız gerekir. Bu, yukarıdaki hizmet hesabı akışına çok benzer ancak ek olarak GoogleCredential.Builder.setServiceAccountUser(String) yöntemini çağırın.
Yüklü uygulamalar
Bu, Yüklü Uygulamalar için OAuth 2.0'ı Kullanma başlıklı makalede açıklanan komut satırı yetkilendirme kodu akışıdır.
Şu kaynaktan örnek snippet: plus-cmdline-sample:
public static void main(String[] args) { try { httpTransport = GoogleNetHttpTransport.newTrustedTransport(); dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR); // authorization Credential credential = authorize(); // set up global Plus instance plus = new Plus.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName( APPLICATION_NAME).build(); // ... } private static Credential authorize() throws Exception { // load client secrets GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(PlusSample.class.getResourceAsStream("/client_secrets.json"))); // set up authorization code flow GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( httpTransport, JSON_FACTORY, clientSecrets, Collections.singleton(PlusScopes.PLUS_ME)).setDataStoreFactory( dataStoreFactory).build(); // authorize return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user"); }
İstemci tarafı uygulamalar
Şu makalede açıklanan tarayıcı tabanlı istemci akışını kullanmak için: İstemci Tarafı Uygulamaları için OAuth 2.0'ı Kullanma, şu adımları uygulamanız gerekir:
- Tarayıcıdaki son kullanıcıyı GoogleBrowserClientRequestUrl ve tarayıcı uygulamanızın son kullanıcının korunan verilerine erişmesine izin verin.
- JavaScript için Google API İstemci Kitaplığı'nı kullanın. yönlendirme URI'sindeki URL parçasında bulunan erişim jetonunu işlemek Google API Konsolu'nda kayıtlı olmalıdır.
Bir web uygulaması için örnek kullanım:
public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException { String url = new GoogleBrowserClientRequestUrl("812741506391.apps.googleusercontent.com", "https://oauth2.example.com/oauthcallback", Arrays.asList( "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile")).setState("/profile").build(); response.sendRedirect(url); }
Android
Android ile kullanılacak kitaplık:
Android için geliştirme yapıyorsanız ve kullanmak istediğiniz Google API'si Google Play Hizmetleri kitaplığı en iyi performans ve deneyim için bu kitaplığı kullanın. Google API'si Google Play Hizmetleri kitaplığının bir parçası olmadığından, Android 4.0 (Ice Cream Sandwich) sürümünü destekleyen Java için Google API İstemci Kitaplığı'nı kullanabilir (veya daha yüksek) ya da burada açıklanmaktadır. Google'da Android desteği Java için API İstemci Kitaplığı @Beta'dır.
Arka plan bilgileri:
Eclair (SDK 2.1) ile başlayarak kullanıcı hesapları Android cihazda yönetilir hesap yöneticisini kullanarak. Tüm Android uygulaması yetkilendirmeleri merkezi olarak tarafından yönetilen bir uygulamadır. AccountManager (Hesap Yöneticisi). Uygulamanızın ihtiyaç duyduğu OAuth 2.0 kapsamını belirtirsiniz ve bir erişim döndürür jeton.
OAuth 2.0 kapsamı, authTokenType
parametresi aracılığıyla oauth2:
olarak belirtilir
artı kapsam. Örneğin:
oauth2:https://www.googleapis.com/auth/tasks
Bu, Google Görevler API'sine okuma/yazma erişimini belirtir. Birden fazla OAuth 2.0 kapsamları için boşlukla ayrılmış liste kullanın.
Bazı API'lerde de çalışan özel authTokenType
parametreleri vardır. Örneğin,
"Görevlerinizi yönetin" yukarıda gösterilen authtokenType
örneğinin takma adıdır.
API anahtarını Google API Konsolu. Aksi takdirde, Hesap Yöneticisi'nin size verdiği jeton yalnızca olup olmadığını kontrol edin. Bu genellikle çok düşüktür. Bunun aksine, anahtarı ile daha yüksek bir ücretsiz kota alabilir ve isteğe bağlı olarak, kullanım için faturalandırmayı ayarlayabilirsiniz. bunun üstünde bir değer var.
Örnek kod snippet'i tasks-android-sample:
com.google.api.services.tasks.Tasks service; @Override public void onCreate(Bundle savedInstanceState) { credential = GoogleAccountCredential.usingOAuth2(this, Collections.singleton(TasksScopes.TASKS)); SharedPreferences settings = getPreferences(Context.MODE_PRIVATE); credential.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null)); service = new com.google.api.services.tasks.Tasks.Builder(httpTransport, jsonFactory, credential) .setApplicationName("Google-TasksAndroidSample/1.0").build(); } private void chooseAccount() { startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQUEST_GOOGLE_PLAY_SERVICES: if (resultCode == Activity.RESULT_OK) { haveGooglePlayServices(); } else { checkGooglePlayServicesAvailable(); } break; case REQUEST_AUTHORIZATION: if (resultCode == Activity.RESULT_OK) { AsyncLoadTasks.run(this); } else { chooseAccount(); } break; case REQUEST_ACCOUNT_PICKER: if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() != null) { String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME); if (accountName != null) { credential.setSelectedAccountName(accountName); SharedPreferences settings = getPreferences(Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); editor.putString(PREF_ACCOUNT_NAME, accountName); editor.commit(); AsyncLoadTasks.run(this); } } break; } }