save and use auth data in box android API - android

I am creating an box android app that allows user to upload media files on their account.
I have set up my client id and client secret,it is authenticating my app too.
Uploading part is also done,but the problem i am facing is to save the auth data [which is obviously needed so user is not needed to login again and again]
Load, save and use of authentication data in Box Android API
the solution given above is not working [may b they have removed 'Utils.parseJSONStringIntoObject' method]
i can store the access token and refresh token but whats the point of saving when i cant use them to re authenticate a user
switch (requestCode)
{
case AUTHENTICATE_REQUEST:
if (resultCode == Activity.RESULT_CANCELED)
{
String failMessage = data.getStringExtra(OAuthActivity.ERROR_MESSAGE);
Toast.makeText(this, "Auth fail:" + failMessage, Toast.LENGTH_LONG).show();
// finish();
}
else
{
BoxAndroidOAuthData oauth = data.getParcelableExtra(OAuthActivity.BOX_CLIENT_OAUTH);
BoxAndroidClient client = new BoxAndroidClient(BoxSDKSampleApplication.CLIENT_ID, BoxSDKSampleApplication.CLIENT_SECRET, null, null);
client.authenticate(oauth);
String ACCESS_TOKEN=oauth.getAccessToken();
String REFRESH_TOKEN=oauth.getRefreshToken();
Editor editor = prefs.edit();
editor.putString("ACCESS_TOKEN", ACCESS_TOKEN);
editor.putString("REFRESH_TOKEN", REFRESH_TOKEN);
editor.commit();
BoxSDKSampleApplication app = (BoxSDKSampleApplication) getApplication();
client.addOAuthRefreshListener(new OAuthRefreshListener()
{
#Override
public void onRefresh(IAuthData newAuthData)
{
Log.d("OAuth", "oauth refreshed, new oauth access token is:" + newAuthData.getAccessToken());
//---------------------------------
BoxOAuthToken oauthObj=null;
try
{
oauthObj=getClient().getAuthData();
}
catch (AuthFatalFailureException e)
{
e.printStackTrace();
}
//saving refreshed oauth object in client
BoxAndroidOAuthData newAuthDataObj=new BoxAndroidOAuthData(oauthObj);
getClient().authenticate(newAuthDataObj);
}
});
app.setClient(client);
}
i have referred https://github.com/box/box-android-sdk-v2/tree/master/BoxSDKSample example
can any one tell me what i am doing wrong or any alternative to authenticate user using authdata,access token,refresh token?
UPDATE
refreshing token as they have said
'Our sdk auto refreshes OAuth access token when it expires. You will want to listen to the refresh events and update your stored token after refreshing.'
mClient.addOAuthRefreshListener(new OAuthRefreshListener()
{
#Override
public void onRefresh(IAuthData newAuthData)
{
Log.d("OAuth", "oauth refreshed, new oauth access token is:" + newAuthData.getAccessToken());
try
{
oauthObj=mClient.getAuthData();
mClient.authenticate(newAuthData);
String authToken=null;
//Storing oauth object in json string format
try
{
authToken = new BoxJSONParser(new AndroidBoxResourceHub()).convertBoxObjectToJSONString(newAuthData);
prefs.edit().putString("BOX_TOKEN", authToken).commit();
//saving authToken in shared Preferences
mClient.authenticate(newAuthData);
String ACCESS_TOKEN=newAuthData.getAccessToken();
String REFRESH_TOKEN=newAuthData.getRefreshToken();
Log.v("New Access token ", oauthObj.getAccessToken());
Log.v("New Refresh token ", oauthObj.getRefreshToken());
editor.putString("ACCESS_TOKEN", ACCESS_TOKEN);
editor.putString("REFRESH_TOKEN", REFRESH_TOKEN);
prefs.edit().putString("BOX_TOKEN", authToken).commit();
editor.commit();
}
catch (BoxJSONException e1)
{
e1.printStackTrace();
}
Log.v("Token Refreshed", " ");
}
catch (AuthFatalFailureException e)
{
e.printStackTrace();
}
}
});
app.setClient(mClient);
}
onClientAuthenticated();
In main activity,fetching stored token
try
{
stored_oauth_token=prefs.getString("BOX_TOKEN", null);
authData = new BoxJSONParser(new AndroidBoxResourceHub()).parseIntoBoxObject(stored_oauth_token, BoxAndroidOAuthData.class);
}
catch (BoxJSONException e)
{
e.printStackTrace();
}
mClient = new BoxAndroidClient(BoxSDKSampleApplication.CLIENT_ID, BoxSDKSampleApplication.CLIENT_SECRET, null, null);
mClient.authenticate(authData);
BoxSDKSampleApplication app = (BoxSDKSampleApplication) getApplication();
app.setClient(mClient);
i tried this app to upload a file after existing ,it did work
but after 60-70 odd minutes i couldn't upload file.
is there anything wrong in my code ?

This is how I initialize my Box client:
mClient = new BoxClient(BOX_CLIENT_ID, BOX_CLIENT_SECRET, null, null);
mClient.addOAuthRefreshListener(new OAuthRefreshListener() {
#Override
public void onRefresh(IAuthData newAuthData) {
try {
String authToken = new BoxJSONParser(new AndroidBoxResourceHub()).convertBoxObjectToJSONString(newAuthData);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putString("box_token", authToken).commit();
} catch (BoxJSONException e) { }
}
});
mAuthToken = prefs.getString("box_token", null);
if (mAuthToken != null) {
BoxAndroidOAuthData authData = new BoxJSONParser(
new AndroidBoxResourceHub()
).parseIntoBoxObject(mAuthToken, BoxAndroidOAuthData.class);
mClient.authenticate(authData);
}
if (!mClient.isAuthenticated()) {
Intent intent = OAuthActivity.createOAuthActivityIntent(context, BOX_CLIENT_ID, BOX_CLIENT_SECRET, false, "https://yoururl.com/");
((Activity) context).startActivityForResult(intent, BOX_AUTH_REQUEST_CODE);
}

So for the auth refresh there are a couple of things to be considered:
box client automatically refreshes OAuth tokens, you'll want to attach a OAuthRefreshListener to listen to the refresh, if you want to persist, persist the oauth data passed into the refresh listener. The listener only update your persisted oauth data, you don't need to re-authenticate in the refresh listener, sdk does the re-authenticate automatically.
When you first initiate box client, you need to authenticate either by persisted auth, or the OAuth UI. The logic should be:
check client.isAuthenticated();
2.1 If authenticated, do nothing.
2.2 if not authenticated, try to check whether there's persisted auth data. If so, authenticate by client.authenticate(oauthdata);
2.3 if 2.2 failed, start OAuth UI flow.
2.4 at last, in case of OAuthFatalFailureException, start OAuth UI flow.

Related

Dropbox falling on browser everytime i upload a file

i have multiple places where my app should upload files to Dropbox. when i try to upload a file the app is falling back to browser. if i use the DropboxApi object globally it says DropboxUnlinkedException.
I am posting my code
Dropbox.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// We create a new AuthSession so that we can use the Dropbox API.
AndroidAuthSession session = buildSession();
AJ_Constant.mApi = new DropboxAPI<AndroidAuthSession>(session);
// Basic Android widgets
// setContentView(R.layout.main);
if (mLoggedIn) {
logOut();
} else {
// Start the remote authentication
AJ_Constant.mApi.getSession().startAuthentication(DropBox.this);
}
}
#Override
protected void onResume() {
super.onResume();
if (session.authenticationSuccessful()) {
try {
// Mandatory call to complete the auth
session.finishAuthentication();
// Store it locally in our app for later use
TokenPair tokens = session.getAccessTokenPair();
storeKeys(tokens.key, tokens.secret);
} catch (IllegalStateException e) {
showToast("Couldn't authenticate with Dropbox:"
+ e.getLocalizedMessage());
Log.i(TAG, "Error authenticating", e);
}
}
}
The code for uploading file is :
(this code is in another file _someX.java)
com.dropbox.client2.DropboxAPI.Entry response = AJ_Constant.mApi.putFile(
AJ_Constant.ReportfileName, inputStream, file.length(),
null, null);
Should i re-build the session or get authentication process done everytime??
Please suggest me any solution
Thanks in advance
From the Android SDK docs (note the last line of code):
A typical authentication flow when no user access token pair is saved
is as follows:
AndroidAuthSession session = new AndroidAuthSession(myAppKeys, myAccessType);
// When user wants to link to Dropbox, within an activity:
session.startOAuth2Authentication(this);
// When user returns to your activity, after authentication:
if (session.authenticationSuccessful()) {
try {
session.finishAuthentication();
AccessTokenPair tokens = session.getAccessTokenPair();
// Store tokens.key, tokens.secret somewhere
} catch (IllegalStateException e) {
// Error handling
}
}
When a user returns to your app and you have tokens stored, just
create a new session with them:
AndroidAuthSession session = new AndroidAuthSession(
myAppKeys, myAccessType, new AccessTokenPair(storedAccessKey, storedAccessSecret));

Android Dropbox API - Cannot save user token after successfull authentication

I am trying to connect my Android 4+ to Dropbox. I am using the latest version of the Core API provided by Dropbox.
Everything works fine until I try to save the user key and token when the user returns to my app after he authenticated the access using dropboxAPI.getSession().startOAuth2Authentication(activity).
When the user returns to my app after the authentication the following code should save key and token:
public boolean completeLogInAfterAuthentication() {
AndroidAuthSession session = dropboxAPI.getSession();
if (session.authenticationSuccessful()) {
try {
// Mandatory call to complete the auth
session.finishAuthentication();
// Store it locally in our app for later use
TokenPair tokens = session.getAccessTokenPair();
saveSessionKeys(tokens.key, tokens.secret);
return true;
} catch (IllegalStateExceptione) {
Log.d("MyLog", "Couldn't authenticate with Dropbox:" + e.getLocalizedMessage());
Log.d("MyLog", "Error authenticating", e);
}
}
return false;
}
This is quite exactly the code that is used in the DBRoulett Demo provided by Dropbox. Problem is, that session.getAccessTokenPair() returns null.
Because of this I cannot store any key or token and the user has to re-login everytime the app is started. How can I solve this?
All information I found just say, that getAccessTokenPair() could fail with an IllegalStateException but this is not the case here. The case that null is returned is not described anywhere. Any idea what I can do?
getAccessTokenPair is used to get an OAuth 1 access token (and secret). But you used OAuth 2, so you want getOAuth2AccessToken. From the tutorial (https://www.dropbox.com/developers/core/start/android):
protected void onResume() {
super.onResume();
if (mDBApi.getSession().authenticationSuccessful()) {
try {
// Required to complete auth, sets the access token on the session
mDBApi.getSession().finishAuthentication();
String accessToken = mDBApi.getSession().getOAuth2AccessToken();
} catch (IllegalStateException e) {
Log.i("DbAuthLog", "Error authenticating", e);
}
}
}
This is roughly the same thing that's in the DBRoulette sample, though it has code for both OAuth 1 and OAuth 2:
private void storeAuth(AndroidAuthSession session) {
// Store the OAuth 2 access token, if there is one.
String oauth2AccessToken = session.getOAuth2AccessToken();
if (oauth2AccessToken != null) {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.putString(ACCESS_KEY_NAME, "oauth2:");
edit.putString(ACCESS_SECRET_NAME, oauth2AccessToken);
edit.commit();
return;
}
// Store the OAuth 1 access token, if there is one. This is only necessary if
// you're still using OAuth 1.
AccessTokenPair oauth1AccessToken = session.getAccessTokenPair();
if (oauth1AccessToken != null) {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.putString(ACCESS_KEY_NAME, oauth1AccessToken.key);
edit.putString(ACCESS_SECRET_NAME, oauth1AccessToken.secret);
edit.commit();
return;
}
}

Storing Access token, Google+ integration Android App

I am new to android and i started with importing sample app from GooglePlayServices in the android SDK.
The app "Plus" allows me to sign-in using G+ credentials. The Sample code is using GoogleApiClient.
This authenticates the App only on client. How do i send access token to my server Or store the access token in to my shared preferences??
Someone please Explain me which file i should add access token code to.?
I am assuming that you are able to login to GooglePlus successfully.Do something like below to get the AccessToken and store it using SharedPreference,
SharedPreferences SharedPreference;
Editor editor;
private class GetGoogleAuthTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String token = null;
try {
token=GoogleAuthUtil.getToken(User_SignUp.this,Plus.AccountApi.getAccountName(mGoogleApiClient),"oauth2:"+Scopes.PLUS_LOGIN+" "+Scopes.PLUS_ME); //Change the permissions as per your need.
} catch (IOException transientEx) {
// Network or server error, try later
Log.e(TAG, transientEx.toString());
} catch (UserRecoverableAuthException e) {
// Recover (with e.getIntent())
Log.e(TAG, e.toString());
// Intent recover = e.getIntent();
// startActivityForResult(recover, REQUEST_CODE_TOKEN_AUTH);
} catch (GoogleAuthException authEx) {
// The call is not ever expected to succeed
// assuming you have already verified that
// Google Play services is installed.
Log.e(TAG, authEx.toString());
}
return token;
}
#Override
protected void onPostExecute(String token) {
if(token!=null)
{
Log.i(TAG, "Access token retrieved:" + token);
SharedPreference = getApplicationContext().getSharedPreferences("TokenPreference", 0);
editor = SharedPreference.edit();
editor.putString("access_token",token);
editor.commit();
}
}
}
Use below snippet where you need to get the accesstoken,
new GetGoogleAuthTask().execute();

Twitter access token and access secret is returning null exception after changing to twitter api version 1.1 in android?

First I am able to login with twitter button with twitter4j-core jar version 2.1.11 and able to retrieve access token and secret. But after twitter has stopped the functionality of API version 1 I have added new twitter4j-core jar version 3.0.3 with API version 1.1. Now I am not able to retrieve the access token and access secret.
Here is database method where I have stored my access token and access secret.
public static void save(Context context, final OAuthConsumer oAuthConsumer) {
SharedPreference.storeValue(OAuth.OAUTH_TOKEN, oAuthConsumer.getToken(), context);
SharedPreference.storeValue(OAuth.OAUTH_TOKEN_SECRET, oAuthConsumer.getTokenSecret(), context);
}
Another Database method where I am retrieving the stored values as:
public static AccessToken retrieveStoredAccessToken(Context context)
{
String token = SharedPreference.getValueFromStore(OAuth.OAUTH_TOKEN , context);
String secret = SharedPreference.getValueFromStore(OAuth.OAUTH_TOKEN_SECRET, context);
return new AccessToken(token, secret);
}
Now when user clicks the login button it will redirect to method isAuthenticated() where I am retrieve stored access token and secret
public static boolean isAuthenticated(Context context)
{
try
{
AccessToken accessToken = Database.retrieveStoredAccessToken(context); // String token and secret is received null from databse
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET);
twitter.setOAuthAccessToken(accessToken);
twitter.getAccountSettings();
return true;
}
catch (TwitterException e)
{
System.out.println("Twitter Authenticated : false");
return false;
}
catch(Exception e)
{
System.out.println("Twitter Authenticated : false");
return false;
}
}
Access token returns Null Exception. I am able to login with twitter but session is not stored because of access token and access secret throws null exception.
following jar file use
1) signpost-commonshttp4-1.2.1.1.jar
2) signpost-core-1.2.1.1.jar
3) twitter4j-core-3.0.3.jar
Finally I have figured my problem.
Just need to change these things:
https://api.twitter.com/oauth/authenticate?force_login=true from http://api.twitter.com/oauth/authenticate

Android: using Google sign in to get access token

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.

Categories

Resources