Load, save and use of authentication data in Box Android API

我只是一个虾纸丫 提交于 2019-12-01 04:32:38

问题


I've been recently trying to implement Box in my Android app. I know how to launch the authentication activity and get BoxAndroidClient object ready to operate on it, but I have got no idea on how to save tokens (SharedPreferences?), load them and then authenticate using loaded tokens, so the user won't have to login to his box account every time he would like to access his files in cloud.

I tried to refresh previously saved tokens (because of Exception that told me that my AccessToken is incorrect).

BoxAndroidOAuthData data = new BoxAndroidOAuthData(new HashMap<String, Object>(){
    private static final long serialVersionUID = 1L;
    {
        put(BoxAndroidOAuthData.FIELD_ACCESS_TOKEN, prefs.acc);
        put(BoxAndroidOAuthData.FIELD_REFRESH_TOKEN, prefs.ref);
        put(BoxAndroidOAuthData.FIELD_EXPIRES_IN, prefs.exp);
        put(BoxAndroidOAuthData.FIELD_TOKEN_TYPE, prefs.typ);
    }
});
data = new BoxAndroidOAuthData(client.getOAuthManager().refreshOAuth(BoxOAuthRequestObject.refreshOAuthRequestObject(data.getRefreshToken(), C, S)));

And I've got another exception:

07-02 22:07:16.433: W/System.err(4684): com.box.restclientv2.exceptions.BoxRestException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'type' that is to contain type id  (for class com.box.boxjavalibv2.dao.BoxServerError)
07-02 22:07:16.433: W/System.err(4684):  at [Source: java.io.StringReader@b55b2c78; line: 1, column: 69]
07-02 22:07:16.433: W/System.err(4684):     at com.box.restclientv2.responseparsers.DefaultBoxJSONResponseParser.parse(DefaultBoxJSONResponseParser.java:75)
07-02 22:07:16.433: W/System.err(4684):     at com.box.boxjavalibv2.responseparsers.ErrorResponseParser.parse(ErrorResponseParser.java:31)
07-02 22:07:16.433: W/System.err(4684):     at com.box.restclientv2.responses.DefaultBoxResponse.parseResponse(DefaultBoxResponse.java:51)
07-02 22:07:16.433: W/System.err(4684):     at com.box.boxjavalibv2.resourcemanagers.BoxResourceManager.getResponseAndParse(BoxResourceManager.java:168)
07-02 22:07:16.433: W/System.err(4684):     at com.box.boxjavalibv2.resourcemanagers.BoxResourceManager.getResponseAndParseAndTryCast(BoxResourceManager.java:143)
07-02 22:07:16.433: W/System.err(4684):     at com.box.boxjavalibv2.resourcemanagers.BoxOAuthManager.refreshOAuth(BoxOAuthManager.java:68)


As I haven't found any tutorials on how to properly do the auth part in Java (samples included in SDK don't cover any method of saving tokens), could anyone provide a good example for that?


回答1:


You shouldn't need to refresh the token yourself, the sdk does it for you. So even your access token is incorrect, as far as the refresh token is correct, the sdk will gets you a new access token.

The BoxAndroidOAuthData object is a parcelable so can be saved this way. It can also be serialized to a json string by toJSONString(new ObjectMapper()) and deserialized from json string by Utils.parseJSONStringIntoObject(jsonString, BoxAndroidOAuthData.class), so it can also be saved to string. Sharedpreference is one of the choices, although it may not be as secure as you want.

As a simplest(not the best) example: 1. save auth: sharedPref.edit().putString("auth", authData.toJSONString(new ObjectMapper()); 2. load auth: BoxAndroidOAuthData authData = Utils.parseJSONStringIntoObject(sharedPref.getString("auth"), BoxAndroidOAuthData.class); boxClient.authenticate(authData); Please note as far as your refresh token in the BoxAndroidOAuthData is still valid, you don't need to worry about refresh the access token, the sdk refreshes it for you. In case your refresh token is invalid, sdk will throw a AuthFatalFailureException and your app need to handle it.




回答2:


This is my way to handle this find below my PreferencesUtil class.

package com.omt.omtboxapi;

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.content.SharedPreferences;

import com.box.boxjavalibv2.dao.BoxOAuthToken;

package com.omt.omtboxapi;

public class PreferencesUtil {

private static PreferencesUtil preferencesUtil;

private PreferencesUtil() {

}

public static PreferencesUtil getInstance() {

    if (preferencesUtil == null) {

        synchronized (PreferencesUtil.class) {

            if (preferencesUtil == null) {
                preferencesUtil = new PreferencesUtil();
            }

        }

    }

    return preferencesUtil;
}

public BoxOAuthToken getAuthToken(Context context) {
    BoxOAuthToken authToken = null;
    SharedPreferences preferences = context.getSharedPreferences(
            "OMT_BOX_SHARED", Context.MODE_PRIVATE);
    if (!preferences.getBoolean("IS_NEW", true)) {

        Map<String, Object> map = new HashMap<String, Object>();

        map.put(BoxOAuthToken.FIELD_ACCESS_TOKEN,
                preferences.getString(BoxOAuthToken.FIELD_ACCESS_TOKEN, ""));
        map.put(BoxOAuthToken.FIELD_REFRESH_TOKEN, preferences.getString(
                BoxOAuthToken.FIELD_REFRESH_TOKEN, ""));
        map.put(BoxOAuthToken.FIELD_TOKEN_TYPE,
                preferences.getString(BoxOAuthToken.FIELD_TOKEN_TYPE, ""));
        map.put(BoxOAuthToken.FIELD_EXPIRES_IN,
                preferences.getInt(BoxOAuthToken.FIELD_EXPIRES_IN, 0));
        authToken = new BoxOAuthToken(map);
    }
    return authToken;
}

public void saveAuthToken(BoxOAuthToken authToken, Context context) {
    SharedPreferences preferences = context.getSharedPreferences(
            "OMT_BOX_SHARED", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = preferences.edit();
    editor.putBoolean("IS_NEW", false);
    editor.putString(BoxOAuthToken.FIELD_ACCESS_TOKEN,
            authToken.getAccessToken());
    editor.putString(BoxOAuthToken.FIELD_REFRESH_TOKEN,
            authToken.getRefreshToken());
    editor.putString(BoxOAuthToken.FIELD_TOKEN_TYPE,
            authToken.getTokenType());
    editor.putInt(BoxOAuthToken.FIELD_EXPIRES_IN, authToken.getExpiresIn());
    editor.commit();
}

}

Now to handle Refresh things below is my approach :

        client.addOAuthRefreshListener(new OAuthRefreshListener() {

            @Override
            public void onRefresh(IAuthData newAuthData) {
                PreferencesUtil.getInstance().saveAuthToken(
                        (BoxOAuthToken) newAuthData, MainActivity.this);
            }
        });

NOTE :

The Keys that I am using in Preference is available in BoxOAuthToken so DO NOT CHANGE IT OTHERWISE YOUR CODE WILL NOT WORK..

THOSE KEYS ARE :

public static final String FIELD_ACCESS_TOKEN = "access_token";
public static final String FIELD_EXPIRES_IN = "expires_in";
public static final String FIELD_TOKEN_TYPE = "token_type";
public static final String FIELD_REFRESH_TOKEN = "refresh_token";


来源:https://stackoverflow.com/questions/17436894/load-save-and-use-of-authentication-data-in-box-android-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!