Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 我应该在SharedReferences中存储具有身份验证令牌属性的用户对象吗?_Android - Fatal编程技术网

Android 我应该在SharedReferences中存储具有身份验证令牌属性的用户对象吗?

Android 我应该在SharedReferences中存储具有身份验证令牌属性的用户对象吗?,android,Android,似乎大家一致建议将身份验证令牌存储在SharedReferences中,如本文所述。但是,我有一个具有多个属性的用户对象,包括id、电子邮件、名称、身份验证令牌,可能还有更多属性。我是否应将身份验证令牌单独存储在SharedReferences中,然后针对每个活动,通过身份验证令牌查找用户: String authenticationToken = User.findByAuthenticationToken(sharedPreferences.getString("authentication

似乎大家一致建议将身份验证令牌存储在SharedReferences中,如本文所述。但是,我有一个具有多个属性的用户对象,包括id、电子邮件、名称、身份验证令牌,可能还有更多属性。我是否应将身份验证令牌单独存储在SharedReferences中,然后针对每个活动,通过身份验证令牌查找用户:

String authenticationToken = User.findByAuthenticationToken(sharedPreferences.getString("authenticationToken"));

或者我应该将对象转换为JSON,然后将整个用户对象存储在SharedReferences中?然后对每个活动进行反序列化。这似乎效率较低

将数据存储在首选项中只是为了将其从一个活动传递到另一个活动是低效的。如果使用DARG2或任何其他依赖注入框架,则可以考虑在用户登录并创建相关用户信息时创建用户模块。然后,您可以通过活动访问此模块并读取用户信息

如果您不使用依赖项注入,您可以对一个单例类执行类似的操作,该类在登录时填充,在注销时清除

编辑:这里是我的一个应用程序的一些摘录(在Kotlin中)

正在检索API请求的令牌:

    val httpClientBuilder = OkHttpClient.Builder()
    if (BuildConfig.DEBUG) {
        val logging = HttpLoggingInterceptor()
        logging.level = HttpLoggingInterceptor.Level.BODY
        httpClientBuilder.addInterceptor(logging)
    }

    httpClientBuilder.addInterceptor { chain ->
        var request = chain.request()
        val token = ObjectGraphController.userComponent?.token
        token?.apply {
            request = request.newBuilder().addHeader("Session-Id", this).build()
        }
        chain.proceed(request)
    }

    val retrofit: Retrofit = Retrofit.Builder()
            .baseUrl(<YOUR ENDPOINT>)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()))
            .client(httpClientBuilder.build())
            .build()
登录和注销时设置/清除组件:

object ObjectGraphController {
    lateinit var objectGraph: ObjectGraph
    var userComponent: UserComponent? = null
        private set

    fun setUserComponent(token: String?) {
        if (token != null) {
            userComponent = objectGraph.userComponent(UserModule(token))
        } else {
            userComponent = null
        }
    }
}

您可以将令牌存储在SharedRefs中,或者使用DI,正如@Francesc所说的

若您正在使用改型,我建议您使用改型实例创建单例(或模块),并将请求拦截器添加到OkHttpClient

 private OkHttpClient buildClient() {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();

    //do any another stuff

    builder.addInterceptor(new RequestAuthInterceptor());

    return builder.build();
}


public static class RequestAuthInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        String jwtToken = SharedPrefs.getKeyJwt();
        if (jwtToken != null) {
            Request.Builder builder = chain.request().newBuilder();
            builder.addHeader("Authorization", jwtToken);
            return chain.proceed(builder.build());
        } else {
            return chain.proceed(chain.request());
        }
    }

}

它不仅仅是从一个活动传递到另一个活动。对于每个JSON API调用,我都需要传递身份验证令牌。因此,这不仅仅是传递给活动。您是否建议仅为此目的使用Dagger2?要在整个应用程序中提供用户模型?人们使用Dagger2是为了这个目的吗?是的,我使用的是Dagger2子模块,当用户登录时实例化,当用户注销时释放该子模块。然后,您可以到处查询该数据。如果你想让用户在应用程序重启后继续登录,你显然仍然需要保存你所需要的信息,但关键是,你可以使用子模块或单例将信息保存在内存中,而不是四处传递,Dagger2对Java/Android来说就像Angular2对JavaScript一样?我不熟悉Angular2。Dagger2是一个依赖注入框架。它特别适合Android,因为它不使用反射(所以没有速度限制),任何问题都会在编译时而不是运行时出现。
 private OkHttpClient buildClient() {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();

    //do any another stuff

    builder.addInterceptor(new RequestAuthInterceptor());

    return builder.build();
}


public static class RequestAuthInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        String jwtToken = SharedPrefs.getKeyJwt();
        if (jwtToken != null) {
            Request.Builder builder = chain.request().newBuilder();
            builder.addHeader("Authorization", jwtToken);
            return chain.proceed(builder.build());
        } else {
            return chain.proceed(chain.request());
        }
    }

}