Skip to content

Instantly share code, notes, and snippets.

@gandharva
Last active June 22, 2016 15:59
Show Gist options
  • Select an option

  • Save gandharva/4f524988ab07a098e56093009db11bca to your computer and use it in GitHub Desktop.

Select an option

Save gandharva/4f524988ab07a098e56093009db11bca to your computer and use it in GitHub Desktop.
This demo shows a scenario where a secured resource is being accessed and the token has expired. The authenticator of the rest client detects the scenario, gets the new access token using refresh token and continues with the call
package io.leftshift.app.model;
import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;
import com.activeandroid.query.Delete;
import com.activeandroid.query.Select;
@Table(name = "Authentication")
public class Authentication extends Model {
private static final String TOKEN_PREFIX = "Bearer ";
//TODO check for data availability else go to login.
@Column (name = "access_token")
public String accessToken;
@Column (name = "refresh_token")
public String refreshToken;
public static boolean detailExists() {
return new Select()
.from(Authentication.class)
.exists();
}
public static Authentication getDetails() {
return new Select()
.from(Authentication.class)
.executeSingle();
}
public String getTokenString() {
return TOKEN_PREFIX + accessToken;
}
public static void saveDetails(String accessToken, String refreshToken) {
clearTable();
Authentication authentication = new Authentication();
authentication.accessToken = accessToken;
authentication.refreshToken = refreshToken;
authentication.save();
}
public static void clearTable() {
new Delete().from(Authentication.class).execute();
}
}
package io.leftshift.app.network;
import io.leftshift.app.BuildConfig;
import io.leftshift.app.model.Authentication;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public class RestClient {
private final Retrofit client;
public RestClient() {
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
httpClientBuilder.authenticator(new TokenAuthenticator());
addAuthorizationInterceptor(httpClientBuilder);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClientBuilder.addInterceptor(httpLoggingInterceptor);
}
client = new Retrofit.Builder()
.baseUrl(BuildConfig.HOST)
.client(httpClientBuilder.build())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
private void addAuthorizationInterceptor(OkHttpClient.Builder httpClientBuilder) {
httpClientBuilder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder()
.headers(original.headers())
.method(original.method(), original.body());
if (Authentication.detailExists()) {
Authentication authentication = Authentication.getDetails();
requestBuilder.addHeader("Authorization", authentication.getTokenString());
}
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
}
public <T> T create(Class<T> apiInterfaceClass) {
return client.create(apiInterfaceClass);
}
}
package io.leftshift.app.network;
import io.leftshift.app.parser.RequestToken;
import io.leftshift.app.parser.ResponseToken;
import java.io.IOException;
import okhttp3.Authenticator;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
import retrofit2.Call;
public class TokenAuthenticator implements Authenticator {
@Override
public Request authenticate(Route route, Response response) throws IOException {
RetrofitService service = new RestClient().create(RetrofitService.class);
Authentication authentication = Authentication.getDetails();
RequestToken requestToken = new RequestToken();
requestToken.setGrantType(RequestToken.GRANT_TYPE_REFRESH_TOKEN);
requestToken.setRefreshToken(authentication.refreshToken);
Call<ResponseToken> call = service.refreshAccessToken(requestToken);
retrofit2.Response<ResponseToken> refreshTokenResponse = call.execute();
if (refreshTokenResponse.isSuccessful()) {
String accessToken = refreshTokenResponse.body().getAccessToken();
String refreshToken = refreshTokenResponse.body().getRefreshToken();
Authentication.saveDetails(accessToken, refreshToken);
authentication = Authentication.getDetails();
return response.request().newBuilder()
.header("Authorization", authentication.getTokenString())
.build();
} else {
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment