Google APIs Client Library for C++ | A C++ library for client applications to access Google APIs. |
This document discusses how to obtain and use OAuth 2.0 credentials using the Google APIs Client Library for C++. It provides a high level overview of the components involved and some basic use cases.
The document Using OAuth 2.0 to Access Google APIs may provide useful supplemental material to understand how to use OAuth 2.0 for authorization works in general.
Contents
Typical use case examples
These examples show how to use the core OAuth 2.0 components to make authorized calls into cloud APIs. The following snippet applies to all the examples in this section.
#include "googleapis/client/auth/file_credential_store.h" #include "googleapis/client/auth/oauth2_authorization.h" #include "googleapis/client/transport/http_authorization.h" using googleapis_client::CredentialStore; using googleapis_client::FileCredentialStoreFactory; using googleapis_client::OAuth2AuthorizationFlow; using googleapis_client::OAuth2Credential; using googleapis_client::OAuth2RequestOptions;
Creating and configuring an OAuth2AuthorizationFlow
Typically flows are created from client secrets files. The Preparing to use the SDK section of the Getting Started document discusses how to obtain a client_secrets file. The Google APIs Console Help may also be of use for more information on creating a client secrets file.
The following snippet:
- Loads a flow definition from a client-secrets file.
- Sets the default OAuth 2.0 scope when asking for credentials.
- Individual requests can override this later.
- Sets a callback for obtaining Authorization Codes.
- This is used to obtain first-time authorization.
- Binds a credential store to remember and recall authorizations.
- See
FileCredentialStoreFactory
in oauth2_authorization.h. - Credentials will be stored in files named
CalendarSample
.
- See
// We're passing in NULL here assuming that you have set // HttpTransport::default_transport_factory. Otherwise instead pass // a transport, such as CurlHttpTransportFactory::New(). flow_.reset( OAuth2AuthorizationFlow::MakeFlowFromClientSecretsPath( client_secrets_path, transport, &status)); CHECK(status.ok()) << status.error_message(); util::Status store_status; string dir; store_status = FileCredentialStoreFactory::GetSystemHomeDirectoryStorePath(&dir); if (store_status.ok()) { FileCredentialStoreFactory store_factory(dir); flow_->ResetCredentialStore( store_factory.NewCredentialStore("CalendarSample", &store_status)); } if (!store_status.ok()) { LOG(WARNING) << "Not adding a credential store: " << store_status.error_message(); } flow_->set_default_scopes(CalendarService::SCOPES::CALENDAR); flow_->mutable_client_spec()->set_redirect_uri( OAuth2AuthorizationFlow::kOutOfBandUrl); flow_->set_authorization_code_callback( NewPermanentCallback(&PromptShellForAuthorizationCode, flow_.get()));
Getting an initial access code without a webserver
The following example is the most primitive way to obtain an
authorization code where your application does not have an embedded
web server to handle a redirect. It uses the
OAuth2AuthorizationFlow::kOutOfBandUrl
redirect, which
just gives the resulting access token directly to the user to
copy and paste back into the application.
static util::Status PromptShellForAuthorizationCode( OAuth2AuthorizationFlow* flow, const OAuth2RequestOptions& options, string* authorization_code) { string url = flow->GenerateAuthorizationCodeRequestUrlWithOptions(options); cout << "Enter the following url into a browser:\n" << url << endl; cout << endl; cout << "Enter the browser's response to confirm authorization: "; authorization_code->clear(); cin >> *authorization_code; if (authorization_code->empty()) { return StatusCanceled("Canceled"); } else { return StatusOk(); } }
Getting an initial access code with an embedded webserver
If your application has a webserver then you can have the OAuth 2.0 server give you the authorization code as a GET request to a URL served by your embedded server. You must register that URL with the application in the Google APIs Console.
The Google APIs Client Library for C++ comes with an embeddable
HTTP server and some support for the time being, however these
will likely change in future releases. It is expected that you
have your own server or will have your own needs so the provided
code is for testing, samples, and illustrative purposes. These
classes have MongooseWebServer
in the name and depend on
the Mongoose web server.
Obtaining and refreshing credentials
The following snippet refreshes a credential for the given user.
- If there is a credential store on the flow, it will be consulted.
- If there is no store or the user has no store credentials then
the flow's AuthorizationCodeCallback will be called and the returned
code turned into an access token (and refresh token).
- The newly obtained credential will be written into the store, if a store is bound to the flow.
- The refresh will fail if there is no AuthorizationCodeCallback or the authorization code could not be turned into an access token.
util::Status RefreshCredentialForUser( const string& id, OAuth2Credential* credential) { OAuth2RequestOptions options; options.user_id = id; return flow_->RefreshCredentialWithOptions(options, credential); }
About authorization codes
The OAuth 2.0 protocol requires a one-time Authorization Code confirming user consent -- the degree of access that the user has granted permission for the application to access. The OAuth 2.0 server can turn the authorization code into a temporary access token and permanent refresh token. Your application will be able to use the refresh token to automatically obtain access tokens the next time the user uses your program. However the first time, you will need to interact with the user to get explicit permission.
Users interact directly with the OAuth 2.0 server to grant permissions
to your application. The
OAuth2AuthorizationFlow::GenerateAuthorizationCodeRequestUrl
method will return a suitable URL with all the necessary information
encoded into it identifying your application and the desired permissions.
The user will authenticate themselves with the OAuth 2.0 server using
the Google Account that they are granting access to. When the user
consents (or rejects) permission, the OAuth 2.0 server will inform
you through the redirect_uri
in the
OAuth2ClientSpec
that you configured the flow
with. For multi-user applications, you can add a state
query parameter to the authorization code request URL and correlate the
state
parameter in the redirect response with your request
so that you know which user the authorization code is for.