196 lines
11 KiB
Plaintext
196 lines
11 KiB
Plaintext
page.title=Authentication
|
|
@jd:body
|
|
|
|
<div id="qv-wrapper">
|
|
<div id="qv">
|
|
<h2>In this document</h2>
|
|
<ol>
|
|
<li><a href="#choose">Choosing an account</a></li>
|
|
<li><a href="#obtain">Obtaining an authorization token</a></li>
|
|
<li><a href="#handle">Handling exceptions</a></li>
|
|
<li><a href="#use">Using the token</a></li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
|
|
<p>
|
|
Google Play services offers a standard authentication flow for all Google APIs and
|
|
all components of Google Play services. In addition, you can leverage the authentication
|
|
portion of the Google Play services SDK to authenticate to services that are not yet supported
|
|
in the Google Play services platform by using the authentication token to manually make API
|
|
requests or using a client library provided by the service provider.
|
|
</p>
|
|
|
|
<p>For implementation details, see the sample in <code><android-sdk>/extras/google-play-services/samples/auth</code>, which shows you how
|
|
to carry out these basic steps for obtaining an authentication token.</p>
|
|
|
|
<h2 id="choose">Choosing an Account</h2>
|
|
<p>
|
|
Google Play services leverage existing accounts on an Android-powered device
|
|
to authenticate to the services that you want to use. To obtain an authorization token,
|
|
a valid Google account is required and it must exist on the device. You can ask your users which
|
|
account they want to use by enumerating the Google accounts on the device or using the
|
|
built-in
|
|
<a href="{@docRoot}google/play-services/reference/com/google/android/gms/common/AccountPicker.html">AccountPicker</a>
|
|
class to display a standard account picker view. You'll need the
|
|
{@link android.Manifest.permission#GET_ACCOUNTS}
|
|
permission set in your manifest file for both methods.
|
|
</p>
|
|
<p>
|
|
For example, here's how to gather all of the Google accounts on a device and return them
|
|
in an array. When obtaining an authorization token, only the email address of the account is
|
|
needed, so that is what the array stores:
|
|
</p>
|
|
|
|
<pre>
|
|
private String[] getAccountNames() {
|
|
mAccountManager = AccountManager.get(this);
|
|
Account[] accounts = mAccountManager.getAccountsByType(
|
|
GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
|
|
String[] names = new String[accounts.length];
|
|
for (int i = 0; i < names.length; i++) {
|
|
names[i] = accounts[i].name;
|
|
}
|
|
return names;
|
|
}
|
|
</pre>
|
|
<h2 id="obtain">Obtaining an Authorization Token</h2>
|
|
<p>
|
|
With an email address, you can now obtain an authorization token. There are two general
|
|
ways to get a token:</p>
|
|
|
|
<ul>
|
|
<li>Call one of the two overloaded <a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/GoogleAuthUtil.html#getToken(android.content.Context, java.lang.String, java.lang.String)">GoogleAuthUtil.getToken()</a> methods in a foreground activity where you can
|
|
display a dialog to the user to interactively handle authentication errors.</li>
|
|
<li>Call one of the three <a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/GoogleAuthUtil.html#getTokenWithNotification(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle)">getTokenWithNotification()</a>
|
|
methods if you are authenticating in a background service or sync adapter so that a notification is displayed if an authentication
|
|
error occurs.</a></li>
|
|
</ul>
|
|
|
|
<h3>Using getToken()</h3>
|
|
The following code snippet obtains an authentication token with an email address, the scope that you want to use for the service, and a {@link android.content.Context}:
|
|
<pre>
|
|
HelloActivity mActivity;
|
|
String mEmail;
|
|
String mScope;
|
|
String token;
|
|
|
|
...
|
|
|
|
try {
|
|
token = GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
|
|
} catch {
|
|
...
|
|
}
|
|
</pre>
|
|
|
|
<p>Call this method off of the main UI thread since it executes network transactions. An easy way to do this
|
|
is in an <a href="http://developer.android.com/reference/android/os/AsyncTask.html">AsyncTask</a>.
|
|
The sample in the Google Play services SDK shows you how to wrap this call in an AsyncTask.
|
|
If authentication is successful, the token is returned. If not, the exceptions described in <a href="#handle">Handling Exceptions</a>
|
|
are thrown that you can catch and handle appropriately.
|
|
</p>
|
|
|
|
<h3>Using getTokenWithNotification()</h3>
|
|
<p>If you are obtaining authentication tokens in a background service or sync adapter, there are three overloaded <code>getTokenWithNotification()</code> methods
|
|
that you can use:</p>
|
|
<ul>
|
|
<li><a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/GoogleAuthUtil.html#getTokenWithNotification(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle)">getTokenWithNotification(Context context, String accountName, String scope, Bundle extras)</a>:
|
|
For background services. Displays a notification to the user when authentication errors occur.</li>
|
|
<li><a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/GoogleAuthUtil.html#getTokenWithNotification(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle, android.content.Intent)">getTokenWithNotification(Context context, String accountName, String scope, Bundle extras, Intent callback)</a>:
|
|
This method is for use in background services. It displays a notification to the user when authentication errors occur. If a user clicks the notification and then authorizes the app to access the account, the intent is broadcasted. When using this method:
|
|
<ul>
|
|
<li>Create a {@link android.content.BroadcastReceiver} that registers the intent and handles it appropriately</li>
|
|
<li>In the app's manifest file, set the <code>android:exported</code> attribute to <code>true</code> for the broadcast receiver</li>
|
|
<li>Ensure that the intent is serializable using the {@link android.content.Intent#toUri toUri(Intent.URI_INTENT_SCHEME)} and
|
|
{@link android.content.Intent#parseUri parseUri(intentUri, Intent.URI_INTENT_SCHEME)} methods.</li>
|
|
</ul>
|
|
<li><a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/GoogleAuthUtil.html#getTokenWithNotification(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle, java.lang.String, android.os.Bundle)">getTokenWithNotification(Context context, String accountName, String scope, Bundle extras, String authority, Bundle syncBundle)</a>: This method is for use in sync adapters. It displays a notification to the user when authentication errors occur. If a user clicks the notification and then authorizes the app to access the account, the sync adapter retries syncing with the information
|
|
contained in the <code>syncBundle</code> parameter.</li>
|
|
</ul>
|
|
|
|
<p>See the sample in <code><android-sdk>/extras/google-play-services/samples/auth</code> for implementation details.</p>
|
|
|
|
<h2 id="handle">Handling Exceptions</h2>
|
|
<p>
|
|
When requesting an authentication token with
|
|
<a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/GoogleAuthUtil.html#getToken(android.content.Context, java.lang.String, java.lang.String)">GoogleAuthUtil.getToken()</a>,
|
|
the following exceptions can be thrown:
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
<a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/UserRecoverableAuthException.html">UserRecoverableAuthException</a>:
|
|
This exception is thrown when an error occurs that users can resolve, such as not yet granting access to their accounts or if they changed their password.
|
|
This exception class contains a {@link android.app.Activity#getIntent getIntent()}
|
|
method that you can call to obtain an intent that you can use with
|
|
{@link android.app.Activity#startActivityForResult startActivityForResult()}
|
|
to obtain the user's resolution. You will need to handle the
|
|
{@link android.app.Activity#onActivityResult onActivityResult()}
|
|
callback when this activity returns to take action based on the user's actions.
|
|
</li>
|
|
<li>
|
|
<a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/GooglePlayServicesAvailabilityException.html">GooglePlayServicesAvailabilityException</a>:
|
|
This exception is a special case of <a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/UserRecoverableAuthException.html">UserRecoverableAuthException</a>
|
|
and occurs when the actual Google Play services APK is not installed or unavailable.
|
|
This exception provides additional client support to
|
|
handle and fix this issue by providing an error code that describes the exact cause of the problem.
|
|
This exception also contains an intent that you can obtain and use to start
|
|
an activity to resolve the issue.
|
|
</li>
|
|
<li>
|
|
<a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/GoogleAuthException.html">GoogleAuthException</a>:
|
|
This exception is thrown when the authorization fails, such as when an invalid scope is
|
|
specified or if the email address used to authenticate is actually not on the user's
|
|
device.
|
|
</li>
|
|
<li>
|
|
<a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/UserRecoverableNotifiedException.html">UserRecoverableNotifiedException</a>:
|
|
This exception is thrown when the authorization fails using one of the <code>getTokenWithNotification()</code> methods and if the error
|
|
is recoverable with a user action.
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
For more information on how to handle these exceptions and code snippets, see the reference
|
|
documentation for the
|
|
<a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/GoogleAuthUtil.html">GoogleAuthUtil</a>
|
|
class.
|
|
</p>
|
|
<h2 id="use">Using the Token</h2>
|
|
<p>
|
|
Once you have successfully obtained a token, you can use it to access Google services.
|
|
Many Google services provide client libraries, so it is recommended that you use these when
|
|
possible, but you can make raw HTTP requests as well with the token. The following example
|
|
shows you how to do this and handle HTTP error and success responses accordingly:
|
|
</p>
|
|
|
|
<pre>
|
|
URL url = new URL("https://www.googleapis.com/oauth2/v1/userinfo?access_token="
|
|
+ token);
|
|
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
|
int serverCode = con.getResponseCode();
|
|
//successful query
|
|
if (serverCode == 200) {
|
|
InputStream is = con.getInputStream();
|
|
String name = getFirstName(readResponse(is));
|
|
mActivity.show("Hello " + name + "!");
|
|
is.close();
|
|
return;
|
|
//bad token, invalidate and get a new one
|
|
} else if (serverCode == 401) {
|
|
GoogleAuthUtil.invalidateToken(mActivity, token);
|
|
onError("Server auth error, please try again.", null);
|
|
Log.e(TAG, "Server auth error: " + readResponse(con.getErrorStream()));
|
|
return;
|
|
//unknown error, do something else
|
|
} else {
|
|
Log.e("Server returned the following error code: " + serverCode, null);
|
|
return;
|
|
}
|
|
</pre>
|
|
|
|
<p>
|
|
Notice that you must manually invalidate the token if the response from the server
|
|
signifies an authentication error (401). This could mean the authentication token
|
|
being used is invalid for the service's scope or the token may have expired. If this is the
|
|
case, obtain a new token using <a href="{@docRoot}google/play-services/reference/com/google/android/gms/auth/GoogleAuthUtil.html#getToken(android.content.Context, java.lang.String, java.lang.String)">GoogleAuthUtil.getToken()</a>.
|
|
</p> |