GoogleDrive get token + refresh token why is it so complicated? - android

I've spent the last two days searching and researching this matter and I must admit I'm shocked implementing this in Android is so insanely complicated compared to iOS or Windows which I already done!!
I'm trying to obtain a token and a refresh token to send to my back end server so it can handle Drive API calls on the user's behalf and its simply a HUGE mess!
I tried to follow many different blogs, endless different ways from google's developers page, countless posts here and other places.
Nothing works.
Maybe some one here can help me...
Here's my current situation:
First I use
String[] accountTypes = new String[]{"com.google"};
Intent intent = AccountPicker.newChooseAccountIntent(null, null,
accountTypes, false, null, null, null, null);
startActivityForResult(intent, 10001);
to pick an account or register a new google account.
Then, I'm using
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(new NetHttpTransport(),
new JacksonFactory(),
clientId,
secret,
Arrays.asList(DriveScopes.DRIVE)).setAccessType("offline").setApprovalPrompt("force")
.build();
to generate a GoogleAuthorizationCodeFlow object. With this I can get a GoogleAuthorizationCodeTokenRequest. But the response I get only has a token. There is no refresh token.
I already approved the consent dialog that appeared which to my understanding should also provide me with a refresh token afterwards.
What am I doing wrong? Or atleast, is there any where I can find a clear example on how to obtain a refresh token???

Alright, so after digging further... I eventually came across this document.
It basically explains that the token + refresh token are not the responsibility of the app/client, it is the responsibility of the backend server and what the client needs to provide to the backend server is only a temporary authorisation code which is easily obtained using GoogleAuthUtil.getToken(). The server will use that auth code to generate a token and a refresh token for future usage. This is explained here.
I hope this might help some one who encounters this issue in the future.

Related

android get new token from google

I have a app in android which works with the google sheets API and write/reads from a spreadheet.
First time I run the app its all good - I get a token from the GoogleAuthUtil fetchToken method and I can make API calls (followed this page - http://developer.android.com/google/auth/http-auth.html).
After one hour, the token expires and I need to get a new one, and I read that it should be really easy with the google play services, since it handles the refreshing of the token.
The problem is - I don't know how to check if the token is valid, and if its not valid, how to get a new one.
I can't just get a new one, because I don't know if an hour passed since the last time I used the app, and I don't think I should try to get a new token everytime I launch the app.
If someone have any experience working with this, I would appreciate any help.
Been struggling with this for a while. just want to know how to check if token is valid, and if its not valid - how to get a new one!
thanks!

How to get OAuth 2 refresh token using access token

I am developing an app in which i am using OAuth 2.0 to upload data in user Google label. I am able to connect to the users mail and after some time access token expires. How to get new access token using Token refresher?
I am using javamail sample code to authenticate and get access token. I am searching it from many days but did not found any running code. I am new to android, so please provide some code or complete sample code.
I got the answer now i want to share to all of you because many questions are unanswered.
to get a new token first you have to invalidate the token using below code
accountManager.invalidateAuthToken("com.google", token);
after invalidating the token you require to get a new Token, below code provides a new Token
String newToken = AccountManager.get(this).getAuthToken(new Account(account, "com.google"),
AUTH_TOKEN_TYPE, true, null, null).getResult().getString(AccountManager.KEY_AUTHTOKEN);
now you can use your new token to authenticate and login.

How can I get an auth token for multiple scopes using android's account manager

I need to get an oauth token from within an android app that will allow me to connect to my appengine application as well as be able to send emails from the user's account. The problem I've run into is that for some reason there is not really any good documentation on the auth token scopes that are available.
From what I've found you can concat the auth tokens with a space delimeter but I'm having no luck.
accountManager.getAuthToken(account, "oauth2:https://mail.google.com/", null, activity, new AuthTokenCallback(), null);
works just fine to get an email token.
Likewise
accountManager.getAuthToken(account, "ah", null, activity, new AuthTokenCallback(), null);
works great for an app engine token.
However
accountManager.getAuthToken(account, "oauth2:https://mail.google.com/ ah", null, activity, new AuthTokenCallback(), null);
gets me into an error
Couldn't sign in,
There was a problem communicating with Google servers
Try again later
How can I get these two to work together like good little well behaved Google services?
The problem is that you are trying to mix an OAuth 2.0 scope ("https://mail.google.com/") with a ClientLogin scope ("ah") and I do not think this is supported.
When you want a token with many permission levels, you concatenate them with a space delimiter as you say. For OAuth 2 scopes it is done like this: oauth2:{space separated list of scopes}.
When you provide the scope oauth2:https://mail.google.com/ ah it is assumed that both scopes are OAuth 2 scopes. But since "ah" isn't a valid OAuth 2 scope the Google servers won't accept it and instead gives you the error you see.
I'm not aware of any OAuth 2 scope for the App Engine and two older questions here on Stackoverflow from 2011 and 2012 suggests that it doesn't support OAuth 2 yet.

Login to symfony from android device

I have an android app that the user logs in to via facebook. I am trying to access my symfony api without logging in another time. Is it possible to log in to symfony with just the access token that I get from the android app?
Yes, it is possible. You'll need to implement a custom authentication provider and possibly a custom user provider to authenticate a user with token (and possibly retrieve him by token).
Ok so just a wrapup of what I managed to do.
I tried to modify fosFacebookBundle to accept access_tokens but in the end of the day I had to just do everything from scratch following the links I got from Zalas. I got the user from the accesstoken via the FacebookProvider class in fosFacebookBundle.
I had to inject Facebook, and FacebookProvider into my FacebookTokenListener. I am not even shure that this is secure. Somebody might be able to login with a access token from another site(I havn't tested it yet). The accesstoken is also in plaintext in the header. All in all not a very nice solution.
$this->facebook->setAccessToken($request->headers->get("access_token"));
$fbUid = $this->facebook->getUser();
if(!$fbUid){
throw new AccessDeniedHttpException("invalid access token");
}
$user = $this->facebookProvider->findUserByFbId($fbUid);
$token = new FacebookTokenToken($user);
Thanks for the links!

How to refresh Token in GoogleCredential

I have implement function retrieve credentials from saved token in SharedPreferences.
mCredential = new GoogleCredential.Builder()
.setClientSecrets(CLIENT_ID, CLIENT_SECRET)
.setJsonFactory(mJsonFactory)
.setTransport(mHttpTransport).build();
mCredential.setRefreshToken(accessRefreshTokenSave);
mCredential.setAccessToken(accessTokenSave);
Long expires = mCredential.getExpiresInSeconds();
boolean result = mCredential.refreshToken();
When the token is expired. We should call mCredential.refreshToken() to refresh the token, is it right ?
When i call refreshToken i got exception.
com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_grant"
}
What should i need to do to refresh the token ? I found some document in Using OAuth 2.0 say about refresh token. But i don't know how to implement it in Android code? Is there any sample code do this ?
Generally (in my experience, since I haven't found any documentation) 'invalid grant' means there is some problem with your stored refresh token. This includes (I think):-
The user has revoked it
Your testing has caused multiple refresh tokens to be generated. Only 25 may be extant
The scopes associated with the stored token have changed
To recover the situation, delete the stored refresh token and start the process again. The good news, is that apart from the user revocation scenario (1) this is a testing environment issue and doesn't necessarily mean you have a bug.
Have a look on https://developers.google.com/+/mobile/android/sign-in that's the OAUTH for Android, and you can check what is wrong, or maybe use the example code in your Project. To give you more details, you have to post the entire project (linking it to GitHub for example) or post the interested Class ;-)

Categories

Resources