0
votes

I am accessing a REST API through Retrofit and a bearer token must be added to each request. The bearer token expires after an hour and at that point needs to be refreshed. To refresh the token, I have a Retrofit Authenticator that gets a new bearer token when a 401 is given and the API request continues normally. I also have an OkHttp Interceptor that adds the renewed token to every request. I would like to save the bearer token to SharedPreferences and have the Interceptor use it until a 401 is given, and the Authenticator is called again.

I am very new to MVVM and do not know where I should put the token saving logic. Since using a bearer token is so critical to accessing data, I think it might make sense for the Authenticator and Interceptor to handle saving/loading the token. The one downside of this is that this breaks the rule of separation of concerns. Would it make sense for the repository to handle this, if so how could I implement it?

Using MVVM, this is how I would like to manage data.

[     Retrofit    ]-
                   - [Repository] - [ViewModel] - [View]
[SharedPreferences]-

Any advice is greatly appreciated!

2

2 Answers

0
votes

You can have a SharedPreferenceManager class, which handles all your read/writing logic of the shared preference. This class will have a public method to save/read the access token. Now I believe you would have two separate classes for you authenticator and interceptor. Just take this SharedPreferenceManager as a dependency of these two classes(ideally as a constructor argument). Now you can easily store your data in the Authenticator class whenever it expires and read it in the Interceptor class. This also keeps ur classes loosely coupled and doesn't break the separation of concern.

0
votes

I think it might make sense for the Authenticator and Interceptor to handle saving/loading the token. The one downside of this is that this breaks the rule of separation of concerns.

If Interceptor itself contains SharedPref/Database store logic, yes it breaks rules. But if it calls TokenStorage/TokenRepository/TokenManager etc... then it is fine.

Would it make sense for the repository to handle this, if so how could I implement it?

Yes, it makes sense if both Interceptor and Repository are in the same module. Interceptor will call Repository interface and Repository implementation will contain that storage logic.