Retrofit表示注销时存在身份验证令牌

时间:2017-04-20 00:26:09

标签: java android authentication retrofit retrofit2

当我在我的应用程序中登录我的帐户时,我在我的SharedPreferences中保存了一个身份验证令牌,如下所示:

PreferenceUtils.setAuthToken(LoginActivity.this, authToken);

这是我的PreferenceUtils课程:

public class PreferenceUtils {
    public static SharedPreferences getSharedPreferences(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context);
    }

    public static String getAuthToken(Context context) {
        SharedPreferences sp = getSharedPreferences(context);
        return sp.getString("auth_token", null);
    }

    public static void setAuthToken(Context context, final String token) {
        SharedPreferences sp = getSharedPreferences(context);
        sp.edit().putString("auth_token", token).apply();
    }
}

当我退出帐户时,我通过调用logOut()类中的UserUtils方法删除了身份验证令牌:

public class UserUtils {
    public static void logOut(Context context) {
        SharedPreferences prefs = PreferenceUtils.getSharedPreferences(context);
        SharedPreferences.Editor editor = prefs.edit();
        editor.remove("auth_token");
        editor.apply();
    }
}

但是,即使在退出我的帐户并从SharedPreferences中删除身份验证令牌之后,所有Retrofit调用仍然以某种方式保存了身份验证令牌,我不确定如何。

换句话说,当我退出帐户并且Retrofit进行新的调用时,它会打印出我认为在用户退出时删除的身份验证令牌。

只有当我重新启动时,我的应用才能完全删除身份验证令牌。

为什么要这样做?

这是我的Retrofit客户端类(请注意注释):

public class ApiClient {

    public static final String API_BASE_URL = "https://www.example.com/";

    private static OkHttpClient.Builder httpClient =
            new OkHttpClient.Builder();

    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create());

    private static Retrofit retrofit = builder.build();

    private static HttpLoggingInterceptor logging =
            new HttpLoggingInterceptor()
                    .setLevel(HttpLoggingInterceptor.Level.BODY);

    public static Retrofit getRetrofit() {
        return retrofit;
    }

    public static <S> S createService(Class<S> serviceClass) {
        if (!httpClient.interceptors().contains(logging)) {
            httpClient.addInterceptor(logging);
            builder.client(httpClient.build());
            retrofit = builder.build();
        }

        return retrofit.create(serviceClass);
    }

    public static <S> S createService(Class<S> serviceClass, final String authToken) {
        if (authToken != null) {
            httpClient.addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Interceptor.Chain chain) throws IOException {
                    Request original = chain.request();

                    // THIS STILL PRINTS THE AUTH TOKEN EVEN AFTER I'VE
                    // REMOVED IT FROM THE SHARED PREFERENCES
                    Log.d("AUTH TOKEN", authToken);

                    Request.Builder requestBuilder = original.newBuilder()
                            .header("Authorization", "Bearer " + authToken)
                            .method(original.method(), original.body());

                    Request request = requestBuilder.build();
                    return chain.proceed(request);
                }
            });
        }

        OkHttpClient client = httpClient.build();
        Retrofit retrofit = builder.client(client).build();

        return retrofit.create(serviceClass);
    }
}

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

您很可能仍然看到令牌的原因是因为当您从共享首选项中删除令牌时,您永远不会在程序中重置该变量。您需要确保将变量设置为null或为空,而不仅仅是从共享首选项中删除它。

答案 1 :(得分:0)

根据您的要求,这是我以前的评论作为答案:

这是因为您添加的拦截器在createService()中仍然存在。一旦您删除了令牌(或将{{1}}传递给{{1}}方法,您也需要删除拦截器。