Using OAuth 2.0 with the Google API Client Library for Java Stay organized with collections Save and categorize content based on your preferences.
Overview
Purpose: This document explains how to use theGoogleCredentialutility class to do OAuth 2.0 authorization with Google services. Forinformation about the generic OAuth 2.0 functions that we provide, seeOAuth 2.0 and the Google OAuth Client Library for Java.
Summary: To access protected data stored on Google services, useOAuth 2.0 for authorization.Google APIs support OAuth 2.0 flows for different types of client applications.In all of these flows, the client application requests an access token that isassociated with only your client application and the owner of the protected databeing accessed. The access token is also associated with a limited scope thatdefines the kind of data your client application has access to (for example"Manage your tasks"). An important goal for OAuth 2.0 is to provide secure andconvenient access to the protected data, while minimizing the potential impactif an access token is stolen.
The OAuth 2.0 packages in the Google API Client Library for Java are built onthe general-purposeGoogle OAuth 2.0 Client Library for Java.
For details, see the Javadoc documentation for the following packages:
- com.google.api.client.googleapis.auth.oauth2(fromgoogle-api-client)
- com.google.api.client.googleapis.extensions.appengine.auth.oauth2(fromgoogle-api-client-appengine)
Google API Console
Before you can access Google APIs, you need to set up a project on theGoogle API Console for auth and billingpurposes, whether your client is an installed application, a mobile application,a web server, or a client that runs in browser.
For instructions on setting up your credentials properly, see theAPI Console Help.
Credential
GoogleCredential
GoogleCredentialis a thread-safe helper class for OAuth 2.0 for accessing protected resourcesusing an access token. For example, if you already have an access token, youcan make a request in the following way:
GoogleCredentialcredential=newGoogleCredential().setAccessToken(accessToken);Plusplus=newPlus.builder(newNetHttpTransport(),GsonFactory.getDefaultInstance(),credential).setApplicationName("Google-PlusSample/1.0").build();
Google App Engine identity
This alternative credential is based on theGoogle App Engine App Identity Java API.Unlike the credential in which a client application requests access to anend-user's data, the App Identity API provides access to the clientapplication's own data.
UseAppIdentityCredential(fromgoogle-api-client-appengine).This credential is much simpler because Google App Engine takes care of all ofthe details. You only specify the OAuth 2.0 scope you need.
Example code taken fromurlshortener-robots-appengine-sample:
staticUrlshortenernewUrlshortener(){AppIdentityCredentialcredential=newAppIdentityCredential(Collections.singletonList(UrlshortenerScopes.URLSHORTENER));returnnewUrlshortener.Builder(newUrlFetchTransport(),GsonFactory.getDefaultInstance(),credential).build();}
Data store
An access token typically has an expiration date of 1 hour, after which you willget an error if you try to use it.GoogleCredentialtakes care of automatically "refreshing" the token, which simply means gettinga new access token. This is done by means of a long-lived refresh token, whichis typically received along with the access token if you use theaccess_type=offline
parameter during the authorization code flow (seeGoogleAuthorizationCodeFlow.Builder.setAccessType(String)).
Most applications will need to persist the credential's access token and/orrefresh token. To persist the credential's access and/or refresh tokens, you canprovide your own implementation ofDataStoreFactorywithStoredCredential;or you can use one of the following implementations provided by the library:
- AppEngineDataStoreFactory:persists the credential using the Google App Engine Data Store API.
- MemoryDataStoreFactory:"persists" the credential in memory, which is only useful as a short-term storage for the lifetime of the process.
- FileDataStoreFactory:persists the credential in a file.
AppEngine Users:AppEngineCredentialStore is deprecated and will be removed soon. We recommend that you useAppEngineDataStoreFactory withStoredCredential. If you have credentials stored in the old fashion, you can use the added helper methodsmigrateTo(AppEngineDataStoreFactory) ormigrateTo(DataStore) to do the migration.
You may useDataStoreCredentialRefreshListenerand set it for the credential usingGoogleCredential.Builder.addRefreshListener(CredentialRefreshListener)).
Authorization code flow
Use the authorization code flow to allow the end-user to grant your applicationaccess to their protected data on Google APIs. The protocol for this flow isspecified inAuthorization Code Grant.
This flow is implemented usingGoogleAuthorizationCodeFlow.The steps are:
- End-user logs in to your application. You will need to associate that userwith a user ID that is unique for your application.
- CallAuthorizationCodeFlow.loadCredential(String))based on the user ID to check if the end-user's credentials are already known.If so, we're done.
- If not, callAuthorizationCodeFlow.newAuthorizationUrl()and direct the end-user's browser to an authorization page to grant yourapplication access to their protected data.
- The Google authorization server will then redirect the browser back to theredirect URL specified by your application, along with a
code
queryparameter. Use thecode
parameter to request an access token usingAuthorizationCodeFlow.newTokenRequest(String)). - UseAuthorizationCodeFlow.createAndStoreCredential(TokenResponse, String))to store and obtain a credential for accessing protected resources.
Alternatively, if you are not usingGoogleAuthorizationCodeFlow, you may use the lower-level classes:
- UseDataStore.get(String) to load the credential from the store based on the user ID.
- UseGoogleAuthorizationCodeRequestUrl to direct the browser to the authorization page.
- UseAuthorizationCodeResponseUrl to process the authorization response and parse the authorization code.
- UseGoogleAuthorizationCodeTokenRequest to request an access token and possibly a refresh token.
- Create a newGoogleCredential and store it usingDataStore.set(String, V).
- Access protected resources using the
GoogleCredential
. Expired access tokens will automatically be refreshed using the refresh token (if applicable). Make sure to useDataStoreCredentialRefreshListener and set it for the credential usingGoogleCredential.Builder.addRefreshListener(CredentialRefreshListener)).
When you set up your project in theGoogle API Console,you select among different credentials, depending on the flow you are using.For more details, seeSetting up OAuth 2.0andOAuth 2.0 Scenarios.Code snippets for each of the flows are below.
Web server applications
The protocol for this flow is explained inUsing OAuth 2.0 for Web Server Applications.
This library provides servlet helper classes to significantly simplify theauthorization code flow for basic use cases. You just provide concrete subclassesofAbstractAuthorizationCodeServletandAbstractAuthorizationCodeCallbackServlet(fromgoogle-oauth-client-servlet)and add them to your web.xml file. Note that you still need to take care of userlogin for your web application and extract a user ID.
publicclassCalendarServletSampleextendsAbstractAuthorizationCodeServlet{@OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{// do stuff}@OverrideprotectedStringgetRedirectUri(HttpServletRequestreq)throwsServletException,IOException{GenericUrlurl=newGenericUrl(req.getRequestURL().toString());url.setRawPath("/oauth2callback");returnurl.build();}@OverrideprotectedAuthorizationCodeFlowinitializeFlow()throwsIOException{returnnewGoogleAuthorizationCodeFlow.Builder(newNetHttpTransport(),GsonFactory.getDefaultInstance(),"[[ENTER YOUR CLIENT ID]]","[[ENTER YOUR CLIENT SECRET]]",Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();}@OverrideprotectedStringgetUserId(HttpServletRequestreq)throwsServletException,IOException{// return user ID}}publicclassCalendarServletCallbackSampleextendsAbstractAuthorizationCodeCallbackServlet{@OverrideprotectedvoidonSuccess(HttpServletRequestreq,HttpServletResponseresp,Credentialcredential)throwsServletException,IOException{resp.sendRedirect("/");}@OverrideprotectedvoidonError(HttpServletRequestreq,HttpServletResponseresp,AuthorizationCodeResponseUrlerrorResponse)throwsServletException,IOException{// handle error}@OverrideprotectedStringgetRedirectUri(HttpServletRequestreq)throwsServletException,IOException{GenericUrlurl=newGenericUrl(req.getRequestURL().toString());url.setRawPath("/oauth2callback");returnurl.build();}@OverrideprotectedAuthorizationCodeFlowinitializeFlow()throwsIOException{returnnewGoogleAuthorizationCodeFlow.Builder(newNetHttpTransport(),GsonFactory.getDefaultInstance()"[[ENTER YOUR CLIENT ID]]","[[ENTER YOUR CLIENT SECRET]]",Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();}@OverrideprotectedStringgetUserId(HttpServletRequestreq)throwsServletException,IOException{// return user ID}}
Google App Engine applications
The authorization code flow on App Engine is almost identical to the servletauthorization code flow, except that we can leverage Google App Engine'sUsers Java API. The userneeds to be logged in for the Users Java API to be enabled; for information aboutredirecting users to a login page if they are not already logged in, seeSecurity and Authentication(in web.xml).
The primary difference from the servlet case is that you provide concretesubclasses ofAbstractAppEngineAuthorizationCodeServlet andAbstractAppEngineAuthorizationCodeCallbackServlet(fromgoogle-oauth-client-appengine.They extend the abstract servlet classes and implement thegetUserId
methodfor you using the Users Java API.AppEngineDataStoreFactory(fromgoogle-http-client-appengine)is a good option for persisting the credential using the Google App Engine DataStore API.
Example taken (slightly modified) fromcalendar-appengine-sample:
publicclassCalendarAppEngineSampleextendsAbstractAppEngineAuthorizationCodeServlet{@OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{// do stuff}@OverrideprotectedStringgetRedirectUri(HttpServletRequestreq)throwsServletException,IOException{returnUtils.getRedirectUri(req);}@OverrideprotectedAuthorizationCodeFlowinitializeFlow()throwsIOException{returnUtils.newFlow();}}classUtils{staticStringgetRedirectUri(HttpServletRequestreq){GenericUrlurl=newGenericUrl(req.getRequestURL().toString());url.setRawPath("/oauth2callback");returnurl.build();}staticGoogleAuthorizationCodeFlownewFlow()throwsIOException{returnnewGoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT,JSON_FACTORY,getClientCredential(),Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();}}publicclassOAuth2CallbackextendsAbstractAppEngineAuthorizationCodeCallbackServlet{privatestaticfinallongserialVersionUID=1L;@OverrideprotectedvoidonSuccess(HttpServletRequestreq,HttpServletResponseresp,Credentialcredential)throwsServletException,IOException{resp.sendRedirect("/");}@OverrideprotectedvoidonError(HttpServletRequestreq,HttpServletResponseresp,AuthorizationCodeResponseUrlerrorResponse)throwsServletException,IOException{Stringnickname=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");}@OverrideprotectedStringgetRedirectUri(HttpServletRequestreq)throwsServletException,IOException{returnUtils.getRedirectUri(req);}@OverrideprotectedAuthorizationCodeFlowinitializeFlow()throwsIOException{returnUtils.newFlow();}}
For an additional sample, seestorage-serviceaccount-appengine-sample.
Service accounts
GoogleCredentialalso supportsservice accounts.Unlike the credential in which a client application requests access to anend-user's data, Service Accounts provide access to the client application'sown data. Your client application signs the request for an access token usinga private key downloaded from theGoogle API Console.
Example code taken fromplus-serviceaccount-cmdline-sample:
HttpTransporthttpTransport=GoogleNetHttpTransport.newTrustedTransport();JsonFactoryjsonFactory=GsonFactory.getDefaultInstance();...// Build service account credential.GoogleCredentialcredential=GoogleCredential.fromStream(newFileInputStream("MyProject-1234.json")).createScoped(Collections.singleton(PlusScopes.PLUS_ME));// Set up global Plus instance.plus=newPlus.Builder(httpTransport,jsonFactory,credential).setApplicationName(APPLICATION_NAME).build();...
For an additional sample, seestorage-serviceaccount-cmdline-sample.
Note: Although you can use service accountsin applications that run from a Google Apps domain, service accounts are notmembers of your Google Apps account and aren't subject to domain policies set byGoogle Apps administrators. For example, a policy set in the Google Apps adminconsole to restrict the ability of Apps end users to share documents outside ofthe domain would not apply to service accounts.Impersonation
You can also use the service account flow to impersonate a user in a domain thatyou own. This is very similar to the service account flow above, but youadditionally callGoogleCredential.Builder.setServiceAccountUser(String).
Installed applications
This is the command-line authorization code flow described inUsing OAuth 2.0 for Installed Applications.
Example snippet fromplus-cmdline-sample:
publicstaticvoidmain(String[]args){try{httpTransport=GoogleNetHttpTransport.newTrustedTransport();dataStoreFactory=newFileDataStoreFactory(DATA_STORE_DIR);// authorizationCredentialcredential=authorize();// set up global Plus instanceplus=newPlus.Builder(httpTransport,JSON_FACTORY,credential).setApplicationName(APPLICATION_NAME).build();// ...}privatestaticCredentialauthorize()throwsException{// load client secretsGoogleClientSecretsclientSecrets=GoogleClientSecrets.load(JSON_FACTORY,newInputStreamReader(PlusSample.class.getResourceAsStream("/client_secrets.json")));// set up authorization code flowGoogleAuthorizationCodeFlowflow=newGoogleAuthorizationCodeFlow.Builder(httpTransport,JSON_FACTORY,clientSecrets,Collections.singleton(PlusScopes.PLUS_ME)).setDataStoreFactory(dataStoreFactory).build();// authorizereturnnewAuthorizationCodeInstalledApp(flow,newLocalServerReceiver()).authorize("user");}
Client-side applications
To use the browser-based client flow described inUsing OAuth 2.0 for Client-side Applications,you would typically follow these steps:
- Redirect the end user in the browser to the authorization page usingGoogleBrowserClientRequestUrlto grant your browser application access to the end user's protected data.
- Use theGoogle API Client Library for JavaScriptto process the access token found in the URL fragment at the redirect URIregistered at theGoogle API Console.
Sample usage for a web application:
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{Stringurl=newGoogleBrowserClientRequestUrl("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
Which library to use with Android:
If you are developing for Android and the Google API you want to use is includedin theGoogle Play Services library,use that library for the best performance and experience. If the Google API youwant to use with Android is not part of the Google Play Services library, youcan use the Google API Client Library for Java, which supports Android 4.0 (Ice Cream Sandwich)(or higher), and which is described here. The support for Android in the GoogleAPI Client Library for Java is@Beta.
Background:
Starting with Eclair (SDK 2.1), user accounts are managed on an Android deviceusing the Account Manager. All Android application authorization is centrallymanaged by the SDK usingAccountManager.You specify the OAuth 2.0 scope your application needs, and it returns an accesstoken to use.
The OAuth 2.0 scope is specified via theauthTokenType
parameter asoauth2:
plus the scope. For example:
oauth2:https://www.googleapis.com/auth/tasks
This specifies read/write access to the Google Tasks API. If you need multipleOAuth 2.0 scopes, use a space-separated list.
Some APIs have specialauthTokenType
parameters that also work. For example,"Manage your tasks" is an alias for theauthtokenType
example shown above.
You must also specify the API key from theGoogle API Console.Otherwise, the token that the AccountManager gives you only provides you withanonymous quota, which is usually very low. By contrast, by specifying an APIkey you receive a higher free quota, and can optionally set up billing for usageabove that.
Example code snippet taken fromtasks-android-sample:
com.google.api.services.tasks.Tasksservice;@OverridepublicvoidonCreate(BundlesavedInstanceState){credential=GoogleAccountCredential.usingOAuth2(this,Collections.singleton(TasksScopes.TASKS));SharedPreferencessettings=getPreferences(Context.MODE_PRIVATE);credential.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME,null));service=newcom.google.api.services.tasks.Tasks.Builder(httpTransport,jsonFactory,credential).setApplicationName("Google-TasksAndroidSample/1.0").build();}privatevoidchooseAccount(){startActivityForResult(credential.newChooseAccountIntent(),REQUEST_ACCOUNT_PICKER);}@OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){super.onActivityResult(requestCode,resultCode,data);switch(requestCode){caseREQUEST_GOOGLE_PLAY_SERVICES:if(resultCode==Activity.RESULT_OK){haveGooglePlayServices();}else{checkGooglePlayServicesAvailable();}break;caseREQUEST_AUTHORIZATION:if(resultCode==Activity.RESULT_OK){AsyncLoadTasks.run(this);}else{chooseAccount();}break;caseREQUEST_ACCOUNT_PICKER:if(resultCode==Activity.RESULT_OK&&data!=null&&data.getExtras()!=null){StringaccountName=data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);if(accountName!=null){credential.setSelectedAccountName(accountName);SharedPreferencessettings=getPreferences(Context.MODE_PRIVATE);SharedPreferences.Editoreditor=settings.edit();editor.putString(PREF_ACCOUNT_NAME,accountName);editor.commit();AsyncLoadTasks.run(this);}}break;}}
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-05-07 UTC.