Implementing Oauth2 Authorization On Android Retrofit

Retrofit Android Library
1 January 2017

How to Refresh Token Oauth2 Retrofit Android

Retrofit is better alternative to volley in terms of ease of use, performance, extensibility and other things. It is a REST client for Android built by Square. By using this tool android developer can make all network stuff much more easier like parsing json, doing crud operations. In this blog we will learn how to handle Oauth2 Protected Api's in retrofit and refresh expired token in retrofit

Step1:- Including Retrofit
For including retrofit we have to add Retrodit dependency in gradle.

dependencies {
      compile fileTree(dir: 'libs', include: ['*.jar'])
      compile 'com.android.support:appcompat-v7:23.4.0'
      compile 'com.squareup.retrofit2:retrofit:2.1.0'
      compile 'com.squareup.retrofit2:converter-gson:2.1.0'
      compile 'com.squareup:otto:1.3.8'
}

Step2:- Adding Internet Permission in Manifest
Since we are using internet connection we have to ask permission to access internet and for that we have to add Internet Permission in Android Manifest file.

<uses-permission android:name="android.permission.INTERNET"/>

If you have your own oauth api its cool but if you dont have a working api or you want a demo api use our api https://www.hashtagsolutions.in/blog/api/token . This api at Post Method and with correct username and password gives access token.

{
     "access_token": "Access Token",
     "expires_in": "Expires In",
     "token_type": "Token Type",
     "refresh_token": "Refresh Token"
}

First we need to create a user and for that we can use following api https://www.hashtagsolutions.in/blog/api/user with Put Method. The Parameter will be json with Name data look like

{
 "username":"Any name",
 "password":"Any Password",
  "first_name":"First Name",
  "last_name":"Last Name",
  "email":"Email Address",
  "city":"City"
}

If everything is ok it will return

{
"status":"ok"
}

Now our user has been created we are all set for next step.

Step3:- Create POJO Class For Token
We need to create a response pojo class which will store all data.

package in.hashtagsolutions.retrofit;

import com.google.gson.annotations.SerializedName;

  public class TokenResponse{

    @SerializedName("access_token")
    private String Token;

    @SerializedName("expires_in")
    private String Expires;

    @SerializedName("token_type")
    private String TokenType;

    @SerializedName("refresh_token")
    private String RefreshToken;

     public String getToken() {
          return TokenType+" "+Token;
    }

    public String getTokenType() {
          return TokenType;
    }

     public String getExpires() {
         return Expires;
    }

    public String getRefreshToken() {
          return RefreshToken;
     }

   }

Step4:- Create Api Interface
We need to create a retrofit api interface class

package in.hashtagsolutions.retrofit;

import in.hashtagsolutions.retrofit.ApiResponse;
import retrofit2.http.GET;
import retrofit2.Call;

  public class ApiInterface{

     @FormUrlEncoded
     @POST("token")
     Call<TokenResponse> getToken(@FieldMap Map<String,String> map);

     @GET("me")
     Call<UserResponse> me(@Header("Authorization") String token);

   }

Step5:- Create Rest Client
Now we need to create retrofit client so we can call it in our main activity

package in.hashtagsolutions.retrofit;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

  public class RestClient{

     public static final String BASE_URL = "https://www.hashtagsolutions.in/blog/api/";

     public static Retrofit getClient() {
          Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
               .addConverterFactory(GsonConverterFactory.create())
               .build();
           return retrofit;
        }

   }

Step6:- Getting Access Token From Activity
Now we just need to get access token from our activity and for that we need client_id and client_secret. If you are using your own api you can get client id and secret from your api provider but if you are using our api's use client_id: 812f12f11808b561439b40639c206429 & client_secret: 7337884022f288672f44f9f251b5d919 .

  public class MainActivity extends AppCompatActivity {

     protected String Client_id = "your_client_id";
     protected String Client_secret = "your_client_secret";

     @Override
     protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       //Creating HashMap
      Map<String,String> map=new HashMap();
      map.put("grant_type","password");
      map.put("client_id","your client id");
      map.put("client_secret","your client secret");
      map.put("username","your username");
      map.put("password","your password");

       //Creating Api Interface
       ApiInterface apiService = RestClient.getClient().create(ApiInterface.class);
       Call <TokenResponse> call = apiService.getToken(map);
        call.enqueue(new Callback<TokenResponse>() {

           @Override
          public void onResponse(Call <TokenResponse>call, Response <TokenResponse> response) {
             TokenResponse tokenResponse = response.body();
             String token= tokenResponse.getToken();
               Log.d("Access Token",token);
             //Save Token For Api Call

           }

           @Override
           public void onFailure(Call<TokenResponse>call, Throwable t) {
             // Log error here since request failed
             Log.e("Error Response", t.toString());
              }
           });
        }

   }

Step7:- Create POJO Class For User Details
We need to create a response pojo class which will store all data.

package in.hashtagsolutions.retrofit;

import com.google.gson.annotations.SerializedName;

  public class UserResponse{

    @SerializedName("first_name")
    private String FirstName;

    @SerializedName("last_name")
    private String LastName;

    @SerializedName("city")
    private String City;

    @SerializedName("email")
    private String Email;

     public String getFirstName() {
          return FirstName;
    }

    public String getLastName() {
          return LastName;
    }

     public String getEmail() {
         return Email;
    }

    public String getCity() {
          return City;
     }

   }

Step8:- Getting data from api using access token header
Now we just need to pass access token in header to get authorized to get data from api

  public class MainActivity extends AppCompatActivity {

     @Override
     protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       //Creating Api Interface
       ApiInterface apiService = RestClient.getClient().create(ApiInterface.class);
       Call <UserResponse> call = apiService.me("Access Token");
        call.enqueue(new Callback<UserResponse>() {

           @Override
          public void onResponse(Call <UserResponse>call, Response <UserResponse> response) {
             UserResponse userResponse = response.body();
             String Name= userResponse.getFirstName()+" "+userResponse.getLastName();
               Log.d("User Name",Name);
             //Do Something from User Data

           }

           @Override
           public void onFailure(Call<UserResponse>call, Throwable t) {
             // Log error here since request failed
             Log.e("Error Response", t.toString());
              }
           });
        }

   }

Step9:- Creating Custom Authenticator
Now we just need to an authenticator which will handle 401 errors which will be when our access token expires and refresh access token and resend request to the api.

  public class TokenAuthenticator implements Authenticator {

     @Override
     public Request authenticate(Route route, Response response) throws IOException {

            //Refresh Your Access Token Here

            return response.request().newBuilder()
           .header("Authorization", AccessToken)
            .build();
        }

   }

Step10:- Create Rest Client with Authenticator
Now we need to create retrofit client with authenticator so we can call it in our activity

package in.hashtagsolutions.retrofit;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

  public class RestClient{

     public static final String BASE_URL = "https://www.hashtagsolutions.in/blog/api/";

     public static Retrofit getClient() {

                OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
                okHttpClient.authenticator(new TokenAuthenticator());

                  Retrofit retrofit = new Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .client(okHttpClient)
                       .addConverterFactory(GsonConverterFactory.create())
                       .build();

                   return retrofit;

        }

   }

Now we are all set whenever refresh token expires our custom authenticator class will refresh access token for us and make the request again.


By Lakshay Jain

Tags: Android, Retrofit