4

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

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

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

我还有另一个例外:

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 中正确执行身份验证部分的教程(SDK 中包含的示例不涵盖任何保存令牌的方法),任何人都可以为此提供一个很好的例子吗?

4

2 回答 2

2

这是我在 PreferencesUtil 类下处理此发现的方法。

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

}

现在处理下面的刷新事情是我的方法:

        client.addOAuthRefreshListener(new OAuthRefreshListener() {

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

笔记 :

我在 Preference 中使用的密钥在 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";
于 2014-05-03T19:49:17.650 回答
2

您不需要自己刷新令牌,sdk 会为您完成。因此,即使您的访问令牌不正确,只要刷新令牌正确,sdk 也会为您获取新的访问令牌。

BoxAndroidOAuthData 对象是可包裹的,因此可以以这种方式保存。也可以通过 toJSONString(new ObjectMapper()) 序列化为 json 字符串,通过 Utils.parseJSONStringIntoObject(jsonString, BoxAndroidOAuthData.class) 从 json 字符串反序列化,所以也可以保存为字符串。Sharedpreference 是其中一种选择,尽管它可能不像您想要的那样安全。

作为一个最简单(不是最好)的例子:1.保存身份验证: sharedPref.edit().putString("auth", authData.toJSONString(new ObjectMapper()); 2.加载身份验证: BoxAndroidOAuthData authData = Utils.parseJSONStringIntoObject(sharedPref.getString("auth"), BoxAndroidOAuthData.class); boxClient.authenticate(authData); 请注意,只要您在 BoxAndroidOAuthData 中的刷新令牌仍然有效,您无需担心刷新访问令牌,SDK为你刷新它。如果您的刷新令牌无效,sdk 将抛出 AuthFatalFailureException 并且您的应用需要处理它。

于 2013-07-03T17:40:47.503 回答