Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to authenticate multiple accounts in Android dropbox sdk 1.5.1?

I need to authenticate multiple accounts

I have searched the forum, and it seems like it is possible So I gave it a try, but I failed

I had tried using the same API APP_KEY & APP_SECRET, it failed Both my session return the same access tokens pair

So I try using different API APP_KEY & APP_SECRET, under same Dropbox account, it failed too

So I try again using different API APP_KEY & APP_SECRET from different Dropbox accounts, it still failed

Anyone can provide me a solution? Thanks in advance

Below is my code, mainly comes from the DBroulette example

onCreate (android)

AndroidAuthSession session = buildSession();
mApi = new DropboxAPI<AndroidAuthSession>(session);
AndroidAuthSession session2 = buildSession2();
mApi2 = new DropboxAPI<AndroidAuthSession>(session2);

onResume (android)

AndroidAuthSession session = mApi.getSession();
if (session.isLinked()) {
dbsetLoggedIn(true);
} else {
dbsetLoggedIn(false);
}
if (session.authenticationSuccessful()) {
try {
session.finishAuthentication();
TokenPair tokens = session.getAccessTokenPair();
dbstoreKeys(tokens.key, tokens.secret);
dbsetLoggedIn(true);
statusTv.append("Dropbox authentication successful\n");
} catch (IllegalStateException e) {
Log.i("Dropbox Error", "Error authenticating", e);
}
}

AndroidAuthSession session2 = mApi2.getSession();
if (session2.isLinked()) {
dbsetLoggedIn2(true);
} else {
dbsetLoggedIn2(false);
}
if (session2.authenticationSuccessful()) {
try {
session2.finishAuthentication();
TokenPair tokens = session2.getAccessTokenPair();
dbstoreKeys2(tokens.key, tokens.secret);
dbsetLoggedIn2(true);
statusTv.append("2Dropbox authentication successful\n");
} catch (IllegalStateException e) {
Log.i("Dropbox Error", "Error authenticating", e);
}
}

OTHERS CODES

private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(Constants.APP_KEY, Constants.APP_SECRET);
AndroidAuthSession session;
String[] stored = getKeys();
if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, Constants.ACCESS_TYPE, accessToken);
} else {
session = new AndroidAuthSession(appKeyPair, Constants.ACCESS_TYPE);
}
return session;
}

private AndroidAuthSession buildSession2() {
AppKeyPair appKeyPair = new AppKeyPair(Constants.APP_KEY2, Constants.APP_SECRET2);
AndroidAuthSession session;
String[] stored = getKeys2();
if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, Constants.ACCESS_TYPE, accessToken);
} else {
session = new AndroidAuthSession(appKeyPair, Constants.ACCESS_TYPE);
}
return session;
}

private String[] getKeys() {
SharedPreferences prefs = getSharedPreferences(Constants.ACCOUNT_PREFS_NAME, 0);
String key = prefs.getString(Constants.ACCESS_KEY_NAME, null);
String secret = prefs.getString(Constants.ACCESS_SECRET_NAME, null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}

private String[] getKeys2() {
SharedPreferences prefs = getSharedPreferences(Constants.ACCOUNT_PREFS_NAME, 0);
String key = prefs.getString(Constants.ACCESS_KEY_NAME2, null);
String secret = prefs.getString(Constants.ACCESS_SECRET_NAME2, null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}

I noticed that I MAYBE need to add something into the manifest in the adding another BUT I cannot add second activity in android manifest with different APP KEY because it will cause duplicated error How can I do it?

<activity
android:name="com.dropbox.client2.android.AuthActivity"
android:configChanges="orientation|keyboard"
android:launchMode="singleTask" >
<intent-filter>
<data android:scheme="db-XXXXXXXXXXXX" />

<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity> 
like image 601
tcboy88 Avatar asked Nov 20 '12 18:11

tcboy88


2 Answers

I'm not sure if this would help you a little bit in your use case, but maybe it could be a workaround to write your own authenticator to use the Android build-in account management to seperate the authentication processes. Here is an example: http://udinic.wordpress.com/2013/04/24/write-your-own-android-authenticator/

like image 126
Patrick Leitermann Avatar answered Nov 10 '22 14:11

Patrick Leitermann


I ran into a similar requirement and this is how I worked around.

1st App
Get access for your first application using the normal dropbox flow.

Note: A likely case for 2 dropbox applications requirement could be accessing user account from your server using a different dropbox application. Please note that you can share the access tokens from 1st app with your server and reuse these credentials safely, provided you are using the same dropbox application on server. If you can't live with that, continue reading.

2nd App
Option 1: Using another Android app

  1. Create another Android App just for the oAuth flow for 2nd dropbox app.
  2. Use Intent to trigger oAuthflow in app2 from app1.
  3. Again, use intent to send back token data from app2 to app1

A few tips, if you are going to use this:

  1. Make the background of App2 oAuth Activity transparent
  2. Remove Intent change animations for app1 <-> app2 transitions
  3. Trigger oAuth in App2 Activity's onCreate

Option 2: If you are keep on doing this with only one Android app, I found a possible workaround as described below.

  1. Prompt your user to open this url: https://www.dropbox.com/1/oauth2/authorize?response_type=code&client_id=APP2_CLIENT_ID
  2. They will have to copy back an authorization code returned by Dropbox
  3. This authorization code can be used to obtain access_tokens for 2nd app

If you are going to use the 2nd app in a server side context, simply share the authorization code with your server. You can obtain tokens from authorization code, in a python flow, like this:

flow = client.DropboxOAuth2FlowNoRedirect(app2_key, app2_secret)
authorize_url = flow.start()
access_token, user_id = flow.finish(auth_code_from_client)

For more generic ways to obtain access_tokens from authorization keys, look at this

like image 1
Praveen Avatar answered Nov 10 '22 12:11

Praveen