I am creating an App Engine project, and I want authenticated access from Google+.
I am now getting the token from the user in this way:
try {
String G_PLUS_SCOPE = "oauth2:https://www.googleapis.com/auth/plus.me";
String USERINFO_SCOPE ="https://www.googleapis.com/auth/userinfo.profile";
String SCOPES = G_PLUS_SCOPE + " " + USERINFO_SCOPE;
token = GoogleAuthUtil.getToken(MainScreenActivity.this, mAccount.name, SCOPES);
} catch (UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), 3);
}
This works, I catch the UserRecoverableAuthException if I have no permission and ask the user with the StartActivityForResult()
But I want to test it some more, looked for a way to revoke the access, but my app is not to be found here: https://security.google.com/settings/security/permissions
How can I revoke the access?
Related
I am working on an Android app which uses google authentication.
I have this code segment:
try {
String token = GoogleAuthUtil.getToken(main, id, "oauth2:profile");
TRC.debug("google token=" + token);
return token;
} catch (UserRecoverableAuthException e) {
main.startActivityForResult(e.getIntent(), 15); // TODO const for 15
I would like to test the catch branch. When I've tried it first I got the google authentication Activity displayed. But when I tried it next time the UserRecoverableAuthException hadn't thrown.
How is it possible to force the app to log out from google?
The documentation here says the following
Warning: The Google+ Sign-In button and the plus.login scope used by
Google+ Sign-In, are not currently supported for use with the Google+
Domains API. Requests that are made to the Google+ Domains API using
an authentication token granted for the
https://www.googleapis.com/auth/plus.login scope, or generated by the
Google+ Sign-In button, will fail.
So if we need to access Google Plus Domains API how do we do it using GoogleApiClient object in android?
I want a list of a user's circles for which I need to use the Domains API.
Consider using GoogleAuthUtil for Google Plus Domain authentication.
And most importantly: "Domain API will work only with domain email id" (which is not the gmail id).
String scopes = "oauth2:" + "https://www.googleapis.com/auth/plus.me " +
"https://www.googleapis.com/auth/plus.circles.read";
String accountName = "domain_email_id_used_for_login";//fetch from AccountManager or ask the user to enter
String token = "";
try {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(LoginActivity.this);
token = sharedPref.getString("token", "");
if (!token.equals("")) {
GoogleAuthUtil.clearToken(LoginActivity.this, token);
}
token = GoogleAuthUtil.getToken(LoginActivity.this,
accountName, scopes);
GoogleCredential googleCredential = new GoogleCredential().setAccessToken(token);
PlusDomains plusDomains = new PlusDomains.Builder(new NetHttpTransport(), new JacksonFactory(), googleCredential).setApplicationName("GPlusLab").build();
plusDomains.people().get("me").execute();
return token;
} catch (UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (GoogleAuthException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
github link to complete example.
I'm trying to develop an app with client-side Google oAuth2.0 authorization for my back-end. I've done all the work needed on the Google developer console.
Google keeps asking for offline access whenever the app requests an authorization token with GoogleAuthUtil.getToken(). I'd like to give the permission once and for all, so the authorization process becomes silent.
Here is the code I use in my authorization AsyncTask.
protected String doInBackground(String... arg0) {
String token = null;
try {
token = GoogleAuthUtil.getToken(mainActivity, mEmail, "oauth2:server:client_id:"+clientId+":api_scope:https://www.googleapis.com/auth/plus.login");
} catch (GooglePlayServicesAvailabilityException playEx) {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
playEx.getConnectionStatusCode(),
mainActivity,
1001);
dialog.show();
} catch (UserRecoverableAuthException recoverableException) {
Intent recoveryIntent = recoverableException.getIntent();
mainActivity.startActivityForResult(recoveryIntent,1001);
// Use the intent in a custom dialog or just startActivityForResult.
Log.e("Auth", "Recoverable authentication exception: " + recoverableException.getMessage(), recoverableException);
} catch (GoogleAuthException authEx) {
// This is likely unrecoverable.
Log.e("Auth", "Unrecoverable authentication exception: " + authEx.getMessage(), authEx);
} catch (IOException ioEx) {
Log.i("Auth", "transient error encountered: " + ioEx.getMessage());
}
return token;
}
Ok, so I finally found something that could help any of you still struggling with this issue.
I changed the scope to something like this:
"audience:server:client_id:" + clientId
That's it. It works, even if the "plus.login" scope is not specified.
Hope this helps!
After reading the last Google + news at here and this. How do I get access token after I complete the sign in?
To answer doubts about oauth scope (just to be useful for googlers):
To fully understand, Google-it some about authentication and authorization concepts.
Check if user/password exists is about authentication part.
Scope is required to authorization part: what you are authorized to do or receive in behalf of user. To get a list of scopes allowed, check the OAuth service documentation.
From Google and G+, most common scopes can be found on: https://developers.google.com/+/api/oauth?hl=pt-ZA
For example, to get all possible information from user, you can use the scope:
"openid profile email https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.me"
(the first word refer to protocol, followed by words that ask for fields on response, and desired scopes can be declared toghether with a space separator)
Note: Later, if you try use your access token to request or do anything that you don't asked before with a scope, the service can return an authorization error.
For Google, a good tool you can use to learn about his OAuth service and scope is the OAuth Playground: https://developers.google.com/oauthplayground/
Did you have a look at the API reference?
The class you are probably looking for is com.google.android.gms.auth.GoogleAuthUtil.
It provides, amongst others, the following method:
static String getToken(Context context, String accountName, String
Description:
Authenticates the user and returns a valid Google authentication token, or throws an exception if there was an error getting a token.
Usage:
String token;
try {
token = GoogleAuthUtil.getToken(context, accountName, scope);
} catch (GooglePlayServicesAvailabilityException playEx) {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
playEx.getConnectionStatusCode(),
Activity.this,
AUTH_REQUEST_CODE);
// Use the dialog to present to the user.
} catch (UserRecoverableAutException recoverableException) {
Intent recoveryIntent = recoverableException.getIntent();
// Use the intent in a custom dialog or just startActivityForResult.
} catch (GoogleAuthException authEx) {
// This is likely unrecoverable.
Log.e(TAG, "Unrecoverable authentication exception: " + authEx.getMesssage(), authEx);
} catch (IOException ioEx) {
Log.i(TAG, "transient error encountered: " + ioEx.getMessage());
doExponentialBackoff();
}
You need to fetch it using async task.
public void onConnected(Bundle connectionHint) {
// Reaching onConnected means we consider the user signed in.
Log.i(TAG, "onConnected");
// Update the user interface to reflect that the user is signed in.
mSignInButton.setEnabled(false);
mSignOutButton.setEnabled(true);
mRevokeButton.setEnabled(true);
// Retrieve some profile information to personalize our app for the user.
Person currentUser = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
AsyncTask<Void, Void, String > task = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
String token = null;
final String SCOPES = "https://www.googleapis.com/auth/plus.login ";
try {
token = GoogleAuthUtil.getToken(
getApplicationContext(),
Plus.AccountApi.getAccountName(mGoogleApiClient),
"oauth2:" + SCOPES);
} catch (IOException e) {
e.printStackTrace();
} catch (GoogleAuthException e) {
e.printStackTrace();
}
return token;
}
#Override
protected void onPostExecute(String token) {
Log.i(TAG, "Access token retrieved:" + token);
}
};
task.execute();
System.out.print("email" + email);
mStatus.setText(String.format(
getResources().getString(R.string.signed_in_as),
currentUser.getDisplayName()));
Plus.PeopleApi.loadVisible(mGoogleApiClient, null)
.setResultCallback(this);
// Indicate that the sign in process is complete.
mSignInProgress = STATE_DEFAULT;
}
Your access token will be stored into token variable.
I need to obtain OAuth2 authentication token to pass it to the server so it can fetch list of Google Reader feeds for the user. Server is .NET - I have no access to it or to it's code but most likely it is using unofficial Reader API
I was able to use Android Account manager to obtain valid token for this purpose with the following code (notice that authTokenType="reader")
Account account = accounts[0];
manager.getAuthToken(account, "reader", null, this, new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> future) {
try {
// If the user has authorized your application to use the tasks API
// a token is available.
String token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN);
// Now you can send the token to API...
cacheManager.putString(GOOGLE_AUTH, token);
GoogleReaderManager.startAddFeedActivity(AddGoogleReaderSourcesActivity.this);
finish();
} catch (OperationCanceledException e) {
Log.e(TAG, "User cancelled", e);
finish();
} catch (Exception e) {
Log.e(TAG, "Failed to obtain Google reader API_KEY", e);
}
}
}, null);
The code above works fine when I send token to the server side .Net app: the app is able to retrieve the list of Reader feeds.
The problem is that this only works for "Google inside" devices. On Nook I have no such luck since there's no way that I was able to find to add Google account to the account manager. So I'm trying to it using OAuth 2 protocol as described here
It works fine as far as obtaining the token: User approves the app from the mobile page which returns the code token which then mobile app exchanges for the Auth token. However this token will not work with the server process. I have a feeling that perhaps I'm using the wrong scope in this URL:
https://accounts.google.com/o/oauth2/auth?response_type=code&scope=https://www.google.com/reader/api/0/subscription/list&redirect_uri=http://localhost&approval_prompt=force&state=/ok&client_id={apps.client.id}
Scopes that I did try in various combinations:
https://www.google.com/reader/api
https://www.google.com/reader/api/0
https://www.google.com/reader/api/0/subscription/list
https://www.google.com/reader/api+https://www.google.com/reader/atom
Here's example of JSON that is returned from get token POST
{"expires_in":3600,
"token_type":"Bearer",
"access_token":"ya29.AHES6ZSEvuUb6Bvd2DNoMnnN_UnfxirZmf_RQjn7LptFLfI",
"refresh_token":"1\/bUwa5MyOtP6VyWqaIEKgfPh08LNdawJ5Qxz6-qZrHg0"}
Am I messing up scope or token type? Not sure how to change a token type. Any other ideas?
P.S. Google account login page asks: Manage your data in Google Reader, that's why I suspect that the scope is wrong
I got it working for https://www.google.com/reader/api/0/subscription/list. So thought of sharing with you.
I have valid access_token:
This is what i tried to resolve it (partially) :
Google provides OAuth 2.o playgound; where they actually simulate all aspects of OAuth 2.0 as well as final API call to fetch data.
I found this very helpful as it clearly shows what is being sent to request.
Here is the URL : https://developers.google.com/oauthplayground/
Using this, i tweaked my api call below and it works :)
public static String getReaderContent(String accessToken){
String url = "https://www.google.com/reader/api/0/subscription/list" ;
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(url);
String response="";
method.setRequestHeader("Authorization", "OAuth "+accessToken);
try {
int statusCode = client.executeMethod(method);
String response= method.getResponseBodyAsString();
System.out.println("response " + responseStr);
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
So this works properly fine for getting subscription list; but have not been able to make it work for reader api which you have mentioned in your question.
Let me know if you have got way around google reader API.