Retrofit2 Authorization - Global Interceptor for access token
You have two choices -- you can add it as a parameter to your call --
@GET("api/Profiles/GetProfile?id={id}")Call<UserProfile> getUser(@Path("id") String id, @Header("Authorization") String authHeader);
This can be a bit annoying because you will have to pass in the "Bearer" + token
on each call. This is suitable if you don't have very many calls that require the token.
If you want to add the header to all requests, you can use an okhttp interceptor --
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request newRequest = chain.request().newBuilder() .addHeader("Authorization", "Bearer " + token) .build(); return chain.proceed(newRequest); } }).build();Retrofit retrofit = new Retrofit.Builder() .client(client) .baseUrl(/** your url **/) .addConverterFactory(GsonConverterFactory.create()) .build();
If you want to add Bearer Token as a Header you can do those types of process.
This is one way to work with Bearer Token
In your Interface
@Headers({ "Content-Type: application/json;charset=UTF-8"})@GET("api/Profiles/GetProfile")Call<UserProfile> getUser(@Query("id") String id, @Header("Authorization") String auth);
After that you will call the Retrofit object in this way
Retrofit retrofit = new Retrofit.Builder() .baseUrl("your Base URL") .addConverterFactory(GsonConverterFactory.create()) .build();APIService client = retrofit.create(APIService.class);Call<UserProfile> calltargetResponse = client.getUser("0034", "Bearer "+token);calltargetResponse.enqueue(new Callback<UserProfile>() { @Override public void onResponse(Call<UserProfile> call, retrofit2.Response<UserProfile> response) { UserProfile UserResponse = response.body(); Toast.makeText(this, " "+response.body(), Toast.LENGTH_SHORT).show(); } @Override public void onFailure(Call<UserProfile> call, Throwable t) { //Toast.makeText(this, "Failed ", Toast.LENGTH_SHORT).show(); }});
Another Way is using intercept, which is similar the previous Answer. But, that time you just need to modify interface little bit like.
@Headers({ "Content-Type: application/json;charset=UTF-8"})@GET("api/Profiles/GetProfile")Call<UserProfile> getUser(@Query("id") String id);
Hope this will work for you.
Based on @iagreen solution kotlin version with different classes and structure suggested by @Daniel Wilson
Make Retrofit instance like this
object RetrofitClientInstance { private var retrofit: Retrofit? = null private val BASE_URL = "http://yoururl" val retrofitInstance: Retrofit? get() { if (retrofit == null) { var client = OkHttpClient.Builder() .addInterceptor(ServiceInterceptor()) //.readTimeout(45,TimeUnit.SECONDS) //.writeTimeout(45,TimeUnit.SECONDS) .build() retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() } return retrofit }}
Add ServiceInterceptor
class like below
class ServiceInterceptor : Interceptor{ var token : String = ""; fun Token(token: String ) { this.token = token; } override fun intercept(chain: Interceptor.Chain): Response { var request = chain.request() if(request.header("No-Authentication")==null){ //val token = getTokenFromSharedPreference(); //or use Token Function if(!token.isNullOrEmpty()) { val finalToken = "Bearer "+token request = request.newBuilder() .addHeader("Authorization",finalToken) .build() } } return chain.proceed(request) }}
Login Interface and data class implementation
interface Login { @POST("Login") @Headers("No-Authentication: true") fun login(@Body value: LoginModel): Call<LoginResponseModel> @POST("refreshToken") fun refreshToken(refreshToken: String): Call<APIResponse<LoginResponseModel>>}data class LoginModel(val Email:String,val Password:String)data class LoginResponseModel (val token:String,val refreshToken:String)
call this in any activity like this
val service = RetrofitClientInstance.retrofitInstance?.create(Login::class.java)val refreshToken = "yourRefreshToken"val call = service?.refreshToken(refreshToken) call?.enqueue(object: Callback<LoginResponseModel>{ override fun onFailure(call: Call<LoginResponseModel>, t: Throwable) { print("throw Message"+t.message) Toast.makeText(applicationContext,"Error reading JSON",Toast.LENGTH_LONG).show() } override fun onResponse(call: Call<LoginResponseModel>, response: Response<LoginResponseModel>) { val body = response?.body() if(body!=null){ //do your work } } })
for detail this video will be helpful.