Skip to content

Instantly share code, notes, and snippets.

@handstandsam
Last active October 4, 2021 20:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save handstandsam/425407658f7ae0be7676de10576dd850 to your computer and use it in GitHub Desktop.
Save handstandsam/425407658f7ae0be7676de10576dd850 to your computer and use it in GitHub Desktop.
Protecting session sensitive responses with Retrofit 2 and okhttp 3
import java.net.SocketTimeoutException;
/** This exception extends {@link SocketTimeoutException} so that okhttp3 will not retry if retry is enabled. */
public class SessionMismatchException extends SocketTimeoutException {
public SessionMismatchException() {
super("Session Mismatch");
}
}
import java.io.IOException;
import android.util.Log;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Call;
/**
* Throw an exception for HTTP responses for invalidated sessions. This will end up calling the Retrofit 2 callback method:
*
* @see retrofit2.Callback#onFailure(Call, Throwable)
*/
public class SessionSensitiveInterceptor implements okhttp3.Interceptor {
private static final String TAG = SessionMismatchException.class.getSimpleName();
private final SessionManager sessionManager;
public SessionSensitiveInterceptor(SessionManager sessionManager) {
this.sessionManager = sessionManager;
}
/**
* Catches the response and before sending it back, makes sure the same Authorization Token is still active.
*/
@Override
public Response intercept(Chain chain) throws IOException {
final Request request = chain.request();
// Execute Request Synchronously and pass through all other interceptors
Response response = chain.proceed(request);
// Request is complete, grab current session token to compare and block if it's changed, but shouldn't have.
final String originalRequestAuthHeader = request.header("Authorization");
final String currentSessionAuthHeader = sessionManager.getAuthorizationHeaderValue();
if (originalRequestAuthHeader == null || originalRequestAuthHeader.length() == 0) {
// Unauthenticated API, this is fine.
return response;
} else if (currentSessionAuthHeader != null && originalRequestAuthHeader.equals(currentSessionAuthHeader)) {
// Authenticated API, same session is active, this is fine.
return response;
} else {
// Authenticated API, but authorization header has changed. Send a custom exception to the failure handler.
SessionMismatchException sessionMismatchException = new SessionMismatchException();
Log.w(TAG, "Session Mismatch", new Exception());
throw sessionMismatchException;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment