How to modify header? retrofit2, sharedpreference - android

I'm making service that makes user able to login in LoginActivity, and if login is successful, user can post something in PostActivity. I'm using Restful api.
I found good sharedpreference example on github : https://gist.github.com/nikhiljha/52d45ca69a8415c6990d2a63f61184ff
and
https://gist.github.com/tsuharesu/cbfd8f02d46498b01f1b
AddCookiesInterceptor.java
public class AddCookiesInterceptor implements Interceptor {
public static final String PREF_COOKIES = "PREF_COOKIES";
private Context context;
public AddCookiesInterceptor(Context context) {
this.context = context;
}
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
HashSet<String> preferences = (HashSet<String>) PreferenceManager.getDefaultSharedPreferences(context).getStringSet(PREF_COOKIES, new HashSet<String>());
for (String cookie : preferences) {
builder.addHeader("Cookie", cookie);
}
return chain.proceed(builder.build());
}
}
RecievedCookiesInterceptor.java
public class ReceivedCookiesInterceptor implements Interceptor {
private Context context;
public ReceivedCookiesInterceptor(Context context) {
this.context = context;
}
#Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
if (!originalResponse.headers("Set-Cookie").isEmpty()) {
HashSet<String> cookies = (HashSet<String>) PreferenceManager.getDefaultSharedPreferences(context).getStringSet("PREF_COOKIES", new HashSet<String>());
for (String header : originalResponse.headers("Set-Cookie")) {
cookies.add(header);
}
SharedPreferences.Editor memes = PreferenceManager.getDefaultSharedPreferences(context).edit();
memes.putStringSet("PREF_COOKIES", cookies).apply();
memes.commit();
}
return originalResponse;
}
}
I used this code very well on my LoginActivity like this,
OkHttpClient client = new OkHttpClient();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.interceptors().add(new AddCookiesInterceptor(getApplicationContext()));
builder.interceptors().add(new RecievedCookiesInterceptor(getApplicationContext()));
client = builder.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(LoginApiService.Login_API_URL)
.build();
loginApiService = retrofit.create(LoginApiService.class);
Call<ResponseBody> getkey = loginApiService.getkey(loginData);
getkey.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.code() == 200) {
startActivity(new Intent(LoginActivity.this, PostActivity.class));
}
}
But in PostActivity, (it's from if (response.code() == 200) startActivity)
I used this like
OkHttpClient client = new OkHttpClient();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.interceptors().add(new AddCookiesInterceptor(getApplicationContext()));
#just used AddCookiesInterceptor, Not RecievedCookiesInterceptor
client = builder.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(PostApiService.Post_API_URL)
.build();
PostApiService = retrofit.create(PostApiService.class);
It give me HTTP/1.1 401 error, I found it means there is problem in Headers.
I write PostApiService like this
public interface PostApiService {
#POST("posts/")
Call<ResponseBody> gettest(#Body TextData textData);}
My question :
I want Header like
key : Authorization //
value : Token e0af91707f0434a1a2a7581dd3f4f483bdd717
Where do i modify?
I know too much codes bothers you maybe, so I have to say i'm very sorry.

Related

Retrofit interface how to add cookies to store data

I have an android studio application that connects to a nodejs backend server with user authentication. I can log in and register from my app but it does not store a session. So I can not get session based functionality yet.
I need to add functionality to store a session. For this how do I do this with the retrofit interface.
I want to log in start a session so I can have user logged in access to other routes on the server.
Or is there another interface for android studio that will allow for cookies and sessions?
Retrofit interface
public interface RetrofitInterface {
#POST("/login")
Call<Login_result> executeLogin(#Body HashMap<String, String> map);
#POST("/signup")
Call<Void> executeSignup(#Body HashMap<String, String>map);
#POST("/add_data")
Call<Void> executeAdd_data(#Body HashMap<String, String>map);
#POST("/logout")
Call<Void> executeLogout(#Body HashMap<String, String>map);
#GET("/test")
Call<Void> executeTest();
}
**Main code**
```java
/*Updated this*/
Context context = this;
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(new OkhttpClient.builder()
.addInterceptor(new ReceivedCookiesInterceptor(context)
.addInterceptor(new AddCookiesInterceptor(context)
).build())
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofitInterface = retrofit.create(RetrofitInterface.class);
Log in code
HashMap<String,String> map = new HashMap<>();
//map.put("email",emailEdit.getText().toString());//
map.put("username", usernameEdit.getText().toString());
map.put("password", passwordEdit.getText().toString());
Call<Login_result> call =
retrofitInterface.executeLogin(map);//Run the post
call.enqueue(new Callback<Login_result>()
{
#Override
public void onResponse(Call<Login_result> call, Response<Login_result> response) {
if(response.code() == 200)
{
/*Login_result result = response.body();
AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this);
builder1.setTitle(result.getUsernname());
builder1.setMessage(result.getEmail());
builder1.show();*/
Toast.makeText(MainActivity.this, "Logged in", Toast.LENGTH_SHORT).show();
}else if(response.code() == 404)
{
Toast.makeText(MainActivity.this, "Incorrect usernanme or password", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<Login_result> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(),Toast.LENGTH_LONG).show();
}
});
You would need to create an two interceptors and store the cookie information in Shared Preferences
public class ReceivedCookiesInterceptor implements Interceptor {
private Context context;
public ReceivedCookiesInterceptor(Context context) {
this.context = context;
}
#Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
if (!originalResponse.headers("Set-Cookie").isEmpty()) {
HashSet<String> cookies = (HashSet<String>) PreferenceManager.getDefaultSharedPreferences(context).getStringSet("PREF_COOKIES", new HashSet<String>());
for (String header : originalResponse.headers("Set-Cookie")) {
cookies.add(header);
}
SharedPreferences.Editor memes = PreferenceManager.getDefaultSharedPreferences(context).edit();
memes.putStringSet("PREF_COOKIES", cookies).apply();
memes.commit();
}
return originalResponse;
}
}
And then reverse to add cookies to the outgoing request
public class AddCookiesInterceptor implements Interceptor {
public static final String PREF_COOKIES = "PREF_COOKIES";
private Context context;
public AddCookiesInterceptor(Context context) {
this.context = context;
}
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
HashSet<String> preferences = (HashSet<String>) PreferenceManager.getDefaultSharedPreferences(context).getStringSet(PREF_COOKIES, new HashSet<String>());
Request original = chain.request();
if(original.url().toString().contains("distributor")){
for (String cookie : preferences) {
builder.addHeader("Cookie", cookie);
}
}
return chain.proceed(builder.build());
}
}
Which then you would need to change your Retrofit instance to the below
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(new OkhttpClient.builder()
.addInterceptor(new ReceivedCookiesInterceptor(context)
.addInterceptor(new AddCookiesInterceptor(context)
).build())
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofitInterface = retrofit.create(RetrofitInterface.class);

Retrofit Logging Error

I am authenticating against an API EndPoint using the Password Grant Flow for OAuth2. The library I am using is Retrofit.
I get the following error:
D/OkHttp: {"error":"invalid_clientId","error_description":"ClientId should be sent."}
I would like to see exactly what API Call I am sending so I can check it for errors.. I have searched the web and found that you need to add a LoggingInterceptor, which I am doing. Still not getting the full API Call..
In my log I get a track of the headers I am sending, as well as the URL, but not the body parameters.. Is there a way to also get the body parameters in the logging?
I would like to see each parameter with its sent value..
The code with provisional credentials can be found at:
https://github.com/NVwingh84/ATTAPITest
Code that I am using is:
public class MainActivity extends AppCompatActivity {
private String grant_type = "password";
private String username = "xxxxx";
private String password = "xxxxx";
private String clientId = "xxxxx";
private String client_secret = "xxxxx";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AccessTokenRequest mytokenrequest = new AccessTokenRequest(grant_type,username,password,clientId,client_secret);
sendNetworkRequest(mytokenrequest);
}
public void sendNetworkRequest(AccessTokenRequest accessTokenRequest){
//create okhttpclientbuilder and set up logging for full logging level "Body"
OkHttpClient.Builder okhttpclientbuilder = new OkHttpClient.Builder();
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//App will only log if you are in development mode
if (BuildConfig.DEBUG){
okhttpclientbuilder.addInterceptor(loggingInterceptor);
}
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("https://api.allthingstalk.io")
.addConverterFactory(GsonConverterFactory.create())
.client(okhttpclientbuilder.build());
Retrofit retrofit = builder.build();
AccessTokenClient client = retrofit.create(AccessTokenClient.class);
Call<AccessTokenRequest> call = client.getAccessToken();
call.enqueue(new Callback() {
#Override
public void onResponse(Call call, Response response) {
Toast.makeText(MainActivity.this, "EndPoint Response", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call call, Throwable t) {
Toast.makeText(MainActivity.this, "Something went wrong", Toast.LENGTH_SHORT).show();
}
});
};
}
Try this code.
add below dependency into app level gradle file..
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
and make separate class for retrofit object define and it is easy to access like below code..
public class ApiClient {
private final static String BASE_URL = "https://dog.ceo/api/breed/";
public static ApiClient apiClient;
private Retrofit retrofit = null;
public static ApiClient getInstance() {
if (apiClient == null) {
apiClient = new ApiClient();
}
return apiClient;
}
//private static Retrofit storeRetrofit = null;
public Retrofit getClient() {
return getClient(null);
}
private Retrofit getClient(final Context context) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.readTimeout(60, TimeUnit.SECONDS);
client.writeTimeout(60, TimeUnit.SECONDS);
client.connectTimeout(60, TimeUnit.SECONDS);
client.addInterceptor(interceptor);
client.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
return chain.proceed(request);
}
});
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
}

How i pass token from java class to retrofit APIClient

I am using retrofit library for parsing data from json.But now i required to pass token in my request. I have set token in one Global class.Now i want to use that token in APIClient.But when i pass , it through null.
This is my APIClient
public class APIClient {
public static final String BASE_URL = "http://kartpays.bizs/api/v5/";
private static Retrofit retrofit = null;
public static final String FOLLOW_URL ="http://kartpays.biz/api/v1/follow/";
public static Retrofit getRetrofitInstance() {
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
Request request = originalRequest.newBuilder()
.header("token", **I want to pass token here**)
.header("Content-Type", "application/json")
.method(originalRequest.method(), originalRequest.body())
.build();
return chain.proceed(request);
}
});
OkHttpClient client = httpClient.build();
retrofit = new Retrofit.Builder()
.baseUrl(FOLLOW_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return retrofit;
}
}
In this class i stored token
public class LibFile {
Context context;
public static SharedPreferences settings;
private static LibFile instance;
public static LibFile getInstance(Context context) {
if (instance == null) {
instance = new LibFile(context);
}
return instance;
}
public LibFile(Context context) {
this.context = context;
settings = context.getSharedPreferences(AppConstants.PREFS_FILE_NAME_PARAM, 0);
}
public String getUser_id() {
return settings.getString("user_id", "");
}
public void setUser_id(String link) {
settings.edit().putString("user_id", link).commit(); //get link from here
}
public String getToken() {
return settings.getString("token","");//pass key here
}
public static void setToken(String userName) {
settings.edit().putString("token", userName).commit();//get key from here
}
public void clearCache() {
settings.edit().clear().commit();
settings.edit().remove("link").commit();
}
}
Please Suggest me how to pass token dynamically. I could not pass static token because it changes continuously.Thanks in advance
If your token is stored in SharedPreference then check out below changes of your code,
public static Retrofit getRetrofitInstance(Context mContext) {
SharedPreferences settings = mContext.getSharedPreferences(AppConstants.PREFS_FILE_NAME_PARAM, 0);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
Request request = originalRequest.newBuilder()
.header("token", settings.getString("token", ""))
.header("Content-Type", "application/json")
.method(originalRequest.method(), originalRequest.body())
.build();
return chain.proceed(request);
}
});
OkHttpClient client = httpClient.build();
retrofit = new Retrofit.Builder()
.baseUrl(FOLLOW_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return retrofit;
}
}
A better solution suiting your code would be:
Request request = originalRequest.newBuilder()
.header("token", LibFile.getInstance(mContext).getToken())
.header("Content-Type", "application/json")
.method(originalRequest.method(), originalRequest.body())
.build();
Check this line: .header("token", LibFile.getInstance(mContext).getToken())
Which take an instance from the LibFile and gets a token.
In your http request, the header key should be "Authorization" instead of "token".
Request request = originalRequest.newBuilder()
.header("Authorization", **I want to pass token here**)
.header("Content-Type", "application/json")
.method(originalRequest.method(), originalRequest.body())
.build();
You can use below methods to put and get token from shared preferences.
public static boolean setStringPreference(String key, String value) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
if (preferences != null && !TextUtils.isEmpty(key)) {
SharedPreferences.Editor editor = preferences.edit();
editor.putString(key, value);
return editor.commit();
}
return false;
}
public static String getStringPreference(String key) {
String value = null;
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
if (preferences != null) {
value = preferences.getString(key, null);
}
return value;
}

Using Interceptors to customize header in Retrofit calls

I am trying to use an Interceptor to add a header when using Retrofit. I think I have created my Interceptor in the right way but I don't know what should I do to call it and connect it with my GET Retrofit method.
This is my Interceptor:
public class HeaderInterceptor
implements Interceptor {
#Override
public Response intercept(Chain chain)
throws IOException {
Request request = chain.request();
request = request.newBuilder()
.addHeader(Constants.VersionHeader.NAME, Constants.VersionHeader.VALUE)
.addHeader("Authorization", "Bearer " + token)
.addHeader("Origin","MY URL")
.build();
Response response = chain.proceed(request);
return response;
}
}
And this is my interface:
public interface CategoryService {
#GET("/v3/projects/{projectId}/categories/")
Call<ArrayList<Category2>> getProjectCategories(#Path("projectId") String projectId);
}
I also have this client which I don't know if I should use it anymore considering that I am using an Interceptor:
public class CategoryClient {
public static final String BASE_URL = "MY URL";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
So I have this GET method getProjectCategories, where I pass the projectID and it returns the contents. What I want to know is how can I call the method using the Interceptor and be able to get the results from the request.
I was able to fix my problem by creating a method called SendNetworkRequest sending the projectId as a parameter, and inside this class I created my OkHttpClient, my Interceptor and my retrofit builder to handle everything that i needed.
private void SendNetworkRequest(String projectID) {
OkHttpClient.Builder okhttpBuilder = new OkHttpClient.Builder();
okhttpBuilder.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder newRequest = request.newBuilder().header("Authorization", "Bearer " + token);
return chain.proceed(newRequest.build());
}
});
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("MY URL")
.client(okhttpBuilder.build())
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
CategoryService category = retrofit.create(CategoryService.class);
Call<ArrayList<Category2>> call = category.getProjectCategories(projectID, token);
call.enqueue(new Callback<ArrayList<Category2>>() {
#Override
public void onResponse(Call<ArrayList<Category2>> call, Response<ArrayList<Category2>> response) {
listCategories = response.body();
listCategories.remove(response.body().size() - 1);
if (response.body().size() > 0){
add_category_layout.setVisibility(View.VISIBLE);
layout_bar.setVisibility(View.VISIBLE);
message_body.setVisibility(View.INVISIBLE);
message_title.setVisibility(View.INVISIBLE);
edit_image.setVisibility(View.INVISIBLE);
adapter2 = new CategoryAdapter2(getApplicationContext(), listCategories);
recyclerView.setAdapter(adapter2);
recyclerView.setVisibility(View.VISIBLE);
}
}
#Override
public void onFailure(Call<ArrayList<Category2>> call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
}

Retrofit and OkHttp basic authentication

I am trying to add basic authentication (username and password) to a Retrofit OkHttp client. This is the code I have so far:
private static Retrofit createMMSATService(String baseUrl, String user, String pass) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
I am using Retrofit 2.2 and this tutorial suggests using AuthenticationInterceptor, but this class is not available.
Where is the correct place to add the credentials? Do I have to add them to my interceptor, client or Retrofit object? And how do I do that?
Find the Solution
1.Write a Interceptor class
import java.io.IOException;
import okhttp3.Credentials;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class BasicAuthInterceptor implements Interceptor {
private String credentials;
public BasicAuthInterceptor(String user, String password) {
this.credentials = Credentials.basic(user, password);
}
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request authenticatedRequest = request.newBuilder()
.header("Authorization", credentials).build();
return chain.proceed(authenticatedRequest);
}
}
2.Finally, add the interceptor to an OkHttp client
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new BasicAuthInterceptor(username, password))
.build();
Retrofit 2
public class ServiceGenerator {
public static final String API_BASE_URL = "https://your.api-base.url";
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();
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null, null);
}
public static <S> S createService(
Class<S> serviceClass, String username, String password) {
if (!TextUtils.isEmpty(username)
&& !TextUtils.isEmpty(password)) {
String authToken = Credentials.basic(username, password);
return createService(serviceClass, authToken);
}
return createService(serviceClass, null);
}
public static <S> S createService(
Class<S> serviceClass, final String authToken) {
if (!TextUtils.isEmpty(authToken)) {
AuthenticationInterceptor interceptor =
new AuthenticationInterceptor(authToken);
if (!httpClient.interceptors().contains(interceptor)) {
httpClient.addInterceptor(interceptor);
builder.client(httpClient.build());
retrofit = builder.build();
}
}
return retrofit.create(serviceClass);
}
}
Retrofit 1.9
public class ServiceGenerator {
public static final String API_BASE_URL = "https://your.api-base.url";
private static RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(API_BASE_URL)
.setClient(new OkClient(new OkHttpClient()));
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null, null);
}
public static <S> S createService(Class<S> serviceClass, String username, String password) {
if (username != null && password != null) {
// concatenate username and password with colon for authentication
String credentials = username + ":" + password;
// create Base64 encodet string
final String basic =
"Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
builder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
request.addHeader("Authorization", basic);
request.addHeader("Accept", "application/json");
}
});
}
RestAdapter adapter = builder.build();
return adapter.create(serviceClass);
}
}
AuthenticationInterceptor.java
public class AuthenticationInterceptor implements Interceptor {
private String authToken;
public AuthenticationInterceptor(String token) {
this.authToken = token;
}
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.header("Authorization", authToken);
Request request = builder.build();
return chain.proceed(request);
}
}
Usage
Retrofit 2
Interface
public interface LoginService {
#POST("/login")
Call<User> basicLogin();
}
Requester
LoginService loginService =
ServiceGenerator.createService(LoginService.class, "user", "secretpassword");
Call<User> call = loginService.basicLogin();
call.enqueue(new Callback<User >() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.isSuccessful()) {
// user object available
} else {
// error response, no access to resource?
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
// something went completely south (like no internet connection)
Log.d("Error", t.getMessage());
}
}
Retrofit 1.9
Interface
public interface LoginService {
#POST("/login")
void basicLogin(Callback<User> cb);
}
Requester
LoginService loginService =
ServiceGenerator.createService(LoginService.class, "user", "secretpassword");
loginService.basicLogin(new Callback<User>() {
#Override
public void success(User user, Response response) {
// user object available
}
#Override
public void failure(RetrofitError error) {
// handle errors, too
}
});
More information see here.
add header interceptor
public class HeaderInterceptor implements Interceptor {
private PreferencesRepository mPrefs;
private String mAuth;
public HeaderInterceptor(PreferencesRepository p) {
mPrefs = p;
}
#Override
public Response intercept(Chain chain) throws IOException {
mAuth = (mPrefs.getAuthToken() != null)?mPrefs.getAuthToken():"";
Request r = chain.request()
.newBuilder()
.addHeader("Accept", "application/json")
// authorization token here
.addHeader("Authorization", "Bearer" + mAuth)
.build();
return chain.proceed(r);
}
}
add cacheinterceptor (optional)
public class CacheInterceptor implements Interceptor {
Context mContext;
public CacheInterceptor(Context context) {
this.mContext = context;
}
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (request.method().equals("GET")) {
if (DeviceUtils.isConnected(mContext)) {
request = request.newBuilder()
.header(Constant.CACHE_CONTROL, "only-if-cached")
.build();
} else {
request = request.newBuilder()
.header(Constant.CACHE_CONTROL, "public, max-stale=2419200")
.build();
}
}
Response originalResponse = chain.proceed(request);
return originalResponse.newBuilder()
.header(Constant.CACHE_CONTROL, "max-age=600")
.build();
}
}
implement it
HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
logger.setLevel(HttpLoggingInterceptor.Level.BODY);
long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(new File(mContext.getCacheDir(), "http"), SIZE_OF_CACHE);
new OkHttpClient.Builder()
.addInterceptor(logger)
.addInterceptor(new HeaderInterceptor(u))
.cache(cache)
.addNetworkInterceptor(new CacheInterceptor(mContext))
.connectTimeout(Constant.CONNECTTIMEOUT, TimeUnit.SECONDS)
.readTimeout(Constant.READTIMEOUT, TimeUnit.SECONDS)
.writeTimeout(Constant.WRITETIMEOUT, TimeUnit.SECONDS)
.build();
Of course using auth interceptor is correct way (as explained in other answers). Although, if you need basic authentication only for single call, then auth header can be added directly in Retrofit request:
import okhttp3.Credentials
// Create credentials
val login = "some login"
val password = "some password"
// Below code will create correct Base64 encoded Basic Auth credentials
val credentials = Credentials.basic(login, password)
// Then in your Retrofit API interface
interface MyApi {
#POST("get_user")
fun getUser(#Header("Authorization") credentials: String): ResponseBody
}

Categories

Resources