Java 在Android API框中加载、保存和使用身份验证数据

Java 在Android API框中加载、保存和使用身份验证数据,java,android,box-api,Java,Android,Box Api,我最近一直在尝试在我的Android应用程序中实现Box。我知道如何启动身份验证活动并让BoxAndroidClient对象准备好对其进行操作,但我不知道如何保存令牌(SharedReferences?),加载它们,然后使用加载的令牌进行身份验证,这样用户就不必每次想访问云中的文件时都登录到他的box帐户。 我试图刷新以前保存的令牌(因为异常告诉我AccessToken不正确) BoxAndroidOAuthData=new BoxAndroidOAuthData(new HashMap()){

我最近一直在尝试在我的Android应用程序中实现Box。我知道如何启动身份验证活动并让BoxAndroidClient对象准备好对其进行操作,但我不知道如何保存令牌(SharedReferences?),加载它们,然后使用加载的令牌进行身份验证,这样用户就不必每次想访问云中的文件时都登录到他的box帐户。

我试图刷新以前保存的令牌(因为异常告诉我AccessToken不正确)

BoxAndroidOAuthData=new BoxAndroidOAuthData(new HashMap()){
私有静态最终长serialVersionUID=1L;
{
put(BoxAndroidOAuthData.FIELD\u ACCESS\u TOKEN,prefs.acc);
put(BoxAndroidOAuthData.FIELD_REFRESH_TOKEN,prefs.ref);
put(BoxAndroidOAuthData.FIELD\u EXPIRES\u IN,prefs.exp);
put(BoxAndroidOAuthData.FIELD\u TOKEN\u TYPE,prefs.typ);
}
});
数据=新的BoxAndroidAuthData(client.getOAuthManager().refreshOAuth(BoxOAuthRequestObject.refreshOAuthRequestObject(data.getRefreshToken(),C,S));
我还有一个例外:

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)


由于我还没有找到任何关于如何在Java中正确执行auth部分的教程(SDK中包含的示例不包括任何保存令牌的方法),有人能提供一个很好的例子吗?

您不需要自己刷新令牌,SDK会为您做这件事。因此,即使您的访问令牌不正确,只要刷新令牌正确,sdk也会为您获取一个新的访问令牌

BoxAndroidAuthData对象是一个可包裹的对象,因此可以通过这种方式保存。它还可以通过toJSONString(new ObjectMapper())序列化为json字符串,并通过Utils.parseJSONStringIntoObject(jsonString,boxandroidauthdata.class)从json字符串反序列化,因此它也可以保存为字符串。SharedReference是一种选择,尽管它可能没有您想要的那么安全

作为一个最简单(不是最好)的例子: 1.保存身份验证:
sharedPref.edit().putString(“auth”,authData.toJSONString(新的ObjectMapper());
2.加载身份验证:
boxandroidauthdataauthdata=Utils.parseJSONStringIntoObject(sharedPref.getString(“auth”),boxandroidauthdata.class);
boxClient.authenticate(authData);

请注意,只要您在AndroidAuthData框中的刷新令牌仍然有效,您就不必担心刷新访问令牌,sdk会为您刷新它。如果您的刷新令牌无效,sdk将抛出AuthFatalFailureException,您的应用程序需要处理它。

这是我在我的首选项SuTil下处理此发现的方法班级

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();
}
注:

我在首选项中使用的密钥在BoxOAuthToken中可用,因此不要更改它,否则您的代码将无法工作

这些关键是:

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";

谢谢这个简单的解决方案。我会在我的代码中添加一些加密,这样令牌会更安全。
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";