Blog : Retrieve and Use OAuth 2.0 Credentials
Retrieve and Use OAuth 2.0 Credentials
Get Started Documentation Examples Support Blog GDG Live
Requests to the Drive API must be authorized using OAuth 2.0 credentials. The samples in this page illustrate how Google Drive apps should retrieve, manage and use such credentials.
Retrieve OAuth 2.0 credentials
Use OAuth 2.0 credentials
Instantiate a service object
Send authorized requests and check for revoked credentials
Next steps
Note: To run these samples, you'll need to provide some basic information, including your client ID and client secret.
To find your project's client ID and client secret, do the following:
Go to the Google Developers Console.
Select a project, or create a new one.
In the sidebar on the left, expand APIs & auth. Next, click APIs. In the list of APIs, make sure the status is ON for the Drive API.
In the sidebar on the left, select Credentials.
If you haven't done so already, create your project's OAuth 2.0 credentials by clicking Create new Client ID, and providing the information needed to create the credentials.
Look for the Client ID and Client secret in the table associated with each of your credentials.
Note that not all types of credentials use both a client ID and client secret and won't be listed in the table if they are not used.
Retrieve OAuth 2.0 credentials
The following code sample shows how to retrieve OAuth 2.0 Credentials using an authorization code.
JavaPythonPHP.NETRubyJavaScript
Replace CLIENTSECRETS_LOCATION value with the location of your client_secrets.json file.
Note: For more information about the OAuth 2.0 package, see OAuth2 API.
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.oauth2.Oauth2;
import com.google.api.services.oauth2.model.Userinfo;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
// ...
class MyClass {
// Path to client_secrets.json which should contain a JSON document such as:
// {
// "web": {
// "client_id": "[[YOUR_CLIENT_ID]]",
// "client_secret": "[[YOUR_CLIENT_SECRET]]",
// "auth_uri": "https://accounts.google.com/o/oauth2/auth",
// "token_uri": "https://accounts.google.com/o/oauth2/token"
// }
// }
private static final String CLIENTSECRETS_LOCATION = "client_secrets.json";
private static final String REDIRECT_URI = "";
private static final List SCOPES = Arrays.asList(
"https://www.googleapis.com/auth/drive.file",
"email",
"profile");
private static GoogleAuthorizationCodeFlow flow = null;
/**
* Exception thrown when an error occurred while retrieving credentials.
*/
public static class GetCredentialsException extends Exception {
protected String authorizationUrl;
/**
* Construct a GetCredentialsException.
*
* @param authorizationUrl The authorization URL to redirect the user to.
*/
public GetCredentialsException(String authorizationUrl) {
this.authorizationUrl = authorizationUrl;
}
/**
* Set the authorization URL.
*/
public void setAuthorizationUrl(String authorizationUrl) {
this.authorizationUrl = authorizationUrl;
}
/**
* @return the authorizationUrl
*/
public String getAuthorizationUrl() {
return authorizationUrl;
}
}
/**
* Exception thrown when a code exchange has failed.
*/
public static class CodeExchangeException extends GetCredentialsException {
/**
* Construct a CodeExchangeException.
*
* @param authorizationUrl The authorization URL to redirect the user to.
*/
public CodeExchangeException(String authorizationUrl) {
super(authorizationUrl);
}
}
/**
* Exception thrown when no refresh token has been found.
*/
public static class NoRefreshTokenException extends GetCredentialsException {
/**
* Construct a NoRefreshTokenException.
*
* @param authorizationUrl The authorization URL to redirect the user to.
*/
public NoRefreshTokenException(String authorizationUrl) {
super(authorizationUrl);
}
}
/**
* Exception thrown when no user ID could be retrieved.
*/
private static class NoUserIdException extends Exception {
}
/**
* Retrieved stored credentials for the provided user ID.
*
* @param userId User's ID.
* @return Stored Credential if found, {@code null} otherwise.
*/
static Credential getStoredCredentials(String userId) {
// TODO: Implement this method to work with your database. Instantiate a new
// Credential instance with stored accessToken and refreshToken.
throw new UnsupportedOperationException();
}
/**
* Store OAuth 2.0 credentials in the application's database.
*
* @param userId User's ID.
* @param credentials The OAuth 2.0 credentials to store.
*/
static void storeCredentials(String userId, Credential credentials) {
// TODO: Implement this method to work with your database.
// Store the credentials.getAccessToken() and credentials.getRefreshToken()
// string values in your database.
throw new UnsupportedOperationException();
}
/**
* Build an authorization flow and store it as a static class attribute.
*
* @return GoogleAuthorizationCodeFlow instance.
* @throws IOException Unable to load client_secrets.json.
*/
static GoogleAuthorizationCodeFlow getFlow() throws IOException {
if (flow == null) {
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(jsonFactory,
MyClass.class.getResourceAsStream(CLIENTSECRETS_LOCATION));
flow =
new GoogleAuthorizationCodeFlow.Builder(httpTransport, jsonFactory, clientSecrets, SCOPES)
.setAccessType("offline").setApprovalPrompt("force").build();
}
return flow;
}
/**
* Exchange an authorization code for OAuth 2.0 credentials.
*
* @param authorizationCode Authorization code to exchange for OAuth 2.0
* credentials.
* @return OAuth 2.0 credentials.
* @throws CodeExchangeException An error occurred.
*/
static Credential exchangeCode(String authorizationCode)
throws CodeExchangeException {
try {
GoogleAuthorizationCodeFlow flow = getFlow();
GoogleTokenResponse response =
flow.newTokenRequest(authorizationCode).setRedirectUri(REDIRECT_URI).execute();
return flow.createAndStoreCredential(response, null);
} catch (IOException e) {
System.err.println("An error occurred: " + e);
throw new CodeExchangeException(null);
}
}
/**
* Send a request to the UserInfo API to retrieve the user's information.
*
* @param credentials OAuth 2.0 credentials to authorize the request.
* @return User's information.
* @throws NoUserIdException An error occurred.
*/
static Userinfo getUserInfo(Credential credentials)
throws NoUserIdException {
Oauth2 userInfoService =
new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credentials).build();
Userinfo userInfo = null;
try {
userInfo = userInfoService.userinfo().get().execute();
} catch (IOException e) {
System.err.println("An error occurred: " + e);
}
if (userInfo != null && userInfo.getId() != null) {
return userInfo;
} else {
throw new NoUserIdException();
}
}
/**
* Retrieve the authorization URL.
*
* @param emailAddress User's e-mail address.
* @param state State for the authorization URL.
* @return Authorization URL to redirect the user to.
* @throws IOException Unable to load client_secrets.json.
*/
public static String getAuthorizationUrl(String emailAddress, String state) throws IOException {
GoogleAuthorizationCodeRequestUrl urlBuilder =
getFlow().newAuthorizationUrl().setRedirectUri(REDIRECT_URI).setState(state);
urlBuilder.set("user_id", emailAddress);
return urlBuilder.build();
}
/**
* Retrieve credentials using the provided authorization code.
*
* This function exchanges the authorization code for an access token and
* queries the UserInfo API to retrieve the user's e-mail address. If a
* refresh token has been retrieved along with an access token, it is stored
* in the application database using the user's e-mail address as key. If no
* refresh token has been retrieved, the function checks in the application
* database for one and returns it if found or throws a NoRefreshTokenException
* with the authorization URL to redirect the user to.
*
* @param authorizationCode Authorization code to use to retrieve an access
* token.
* @param state State to set to the authorization URL in case of error.
* @return OAuth 2.0 credentials instance containing an access and refresh
* token.
* @throws NoRefreshTokenException No refresh token could be retrieved from
* the available sources.
* @throws IOException Unable to load client_secrets.json.
*/
public static Credential getCredentials(String authorizationCode, String state)
throws CodeExchangeException, NoRefreshTokenException, IOException {
String emailAddress = "";
try {
Credential credentials = exchangeCode(authorizationCode);
Userinfo userInfo = getUserInfo(credentials);
String userId = userInfo.getId();
emailAddress = userInfo.getEmail();
if (credentials.getRefreshToken() != null) {
storeCredentials(userId, credentials);
return credentials;
} else {
credentials = getStoredCredentials(userId);
if (credentials != null && credentials.getRefreshToken() != null) {
return credentials;
}
}
} catch (CodeExchangeException e) {
e.printStackTrace();
// Drive apps should try to retrieve the user and credentials for the current
// session.
// If none is available, redirect the user to the authorization URL.
e.setAuthorizationUrl(getAuthorizationUrl(emailAddress, state));
throw e;
} catch (NoUserIdException e) {
e.printStackTrace();
}
// No refresh token has been retrieved.
String authorizationUrl = getAuthorizationUrl(emailAddress, state);
throw new NoRefreshTokenException(authorizationUrl);
}
}
Use OAuth 2.0 credentials
Once OAuth 2.0 credentials have been retrieved as documented in the previous section, they can be used to authorize a Drive service object and send requests to the API. The following code snippets show how to instantiate and authorize a Drive service object and send a request to the Drive API to retrieve a File's metadata.
Instantiate a service object
This section shows how to instantiate a service object and then authorize it to make API requests, using OAuth 2.0 credentials retrieved using the process described in Retrieve OAuth 2.0 Credentials.
JavaPythonPHP.NETRubyJavaScript
session_start();
require_once "google-api-php-client/src/Google_Client.php";
require_once "google-api-php-client/src/contrib/Google_DriveService.php";
// ...
/**
* Build a Drive service object.
*
* @param String credentials Json representation of the OAuth 2.0 credentials.
* @return Google_DriveService service object.
*/
function buildService($credentials) {
$apiClient = new Google_Client();
$apiClient->setUseObjects(true);
$apiClient->setAccessToken($credentials);
return new Google_DriveService($apiClient);
}
// ...
?>
Send authorized requests and check for revoked credentials
The following code snippet uses an authorized Drive service instance and sends an authorized GET request to the Drive API to retrieve a File's metadata. If an error occurs, the code checks for an HTTP 401 status code, which should be handled by redirecting the user to the authorization URL.
To build an authorization URL, refer to the Retrieve OAuth 2.0 Credentials section.
More Drive API operations are documented in the API Reference.
JavaPythonPHP.NETRubyJavaScript
/**
* Print a file's metadata.
*
* @param apiDriveService $service Drive API service instance.
* @param string $fileId ID of the file to print metadata for.
*/
function printFile($service, $fileId) {
try {
$file = $service->files->get($fileId);
print "Title: " . $file->getTitle();
print "Description: " . $file->getDescription();
print "MIME type: " . $file->getMimeType();
} catch (apiAuthException) {
// Credentials have been revoked.
// TODO: Redirect the user to the authorization URL.
throw new RuntimeException('Not implemented!');
} catch (apiException $e) {
print "An error occurred: " . $e->getMessage();
}
}
Next steps
Once you are comfortable authorizing Drive API requests, you're ready to upload files and perform any of the other operations described in "Manage Drive Files." You can learn more about available API methods in the API Reference, and you can review our end-to-end Example Apps to examine some working code.