Android Retrofit2 Refresh Oauth 2 Token

前端 未结 2 799
旧时难觅i
旧时难觅i 2021-01-30 07:17

I am using Retrofit and OkHttp libraries. So I have Authenticator which authanticate user if gets 401 response.

My build.gra

2条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-30 07:43

    In your ApiClient.java class :

    OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .addInterceptor(new AuthorizationInterceptor(context))
                    .build();
    

    Add TokenManager.java class in your retrofit package

    package co.abc.retrofit;
    
    /**
     * Created by ravindrashekhawat on 17/03/17.
     */
    
    public interface TokenManager {
        String getToken();
        boolean hasToken();
        void clearToken();
        String refreshToken();
    }
    

    Add Intercepter class in your package with name AuthorizationInterceptor.java

    package co.smsmagic.retrofit;
    
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.preference.PreferenceManager;
    import android.util.Log;
    
    import com.google.gson.Gson;
    
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import java.io.IOException;
    
    import co.abc.models.RefreshTokenResponseModel;
    import okhttp3.Interceptor;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.RequestBody;
    import okhttp3.Response;
    import okhttp3.ResponseBody;
    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Retrofit;
    import retrofit2.http.Header;
    
    import static co.abc.utils.abcConstants.ACCESS_TOKEN;
    import static co.abc.utils.abcConstants.BASE_URL;
    import static co.abc.utils.abcConstants.GCM_TOKEN;
    import static co.abc.utils.abcConstants.JWT_TOKEN_PREFIX;
    import static co.abc.utils.abcConstants.REFRESH_TOKEN;
    
    /**
     * Created by ravindrashekhawat on 21/03/17.
     */
    
    public class AuthorizationInterceptor implements Interceptor {
        private static Retrofit retrofit = null;
        private static String deviceToken;
        private static String accessToken;
        private static String refreshToken;
        private static TokenManager tokenManager;
        private static Context mContext;
    
        public AuthorizationInterceptor(Context context) {
            this.mContext = context;
        }
    
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Request modifiedRequest = null;
    
            tokenManager = new TokenManager() {
                final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
    
                @Override
                public String getToken() {
    
                    accessToken = sharedPreferences.getString(ACCESS_TOKEN, "");
                    return accessToken;
                }
    
                @Override
                public boolean hasToken() {
                    accessToken = sharedPreferences.getString(ACCESS_TOKEN, "");
                    if (accessToken != null && !accessToken.equals("")) {
                        return true;
                    }
                    return false;
                }
    
                @Override
                public void clearToken() {
                    sharedPreferences.edit().putString(ACCESS_TOKEN, "").apply();
                }
    
                @Override
                public String refreshToken() {
                    final String accessToken = null;
    
                    RequestBody reqbody = RequestBody.create(null, new byte[0]);
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url(BASE_URL + "refresh")
                            .method("POST", reqbody)
                            .addHeader("Authorization", JWT_TOKEN_PREFIX + refreshToken)
                            .build();
    
                    try {
                        Response response = client.newCall(request).execute();
                        if ((response.code()) == 200) {
                            // Get response
                            String jsonData = response.body().string();
    
                            Gson gson = new Gson();
                            RefreshTokenResponseModel refreshTokenResponseModel = gson.fromJson(jsonData, RefreshTokenResponseModel.class);
                            if (refreshTokenResponseModel.getRespCode().equals("1")) {
                                sharedPreferences.edit().putString(ACCESS_TOKEN, refreshTokenResponseModel.getResponse()).apply();
                                return refreshTokenResponseModel.getResponse();
                            }
    
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return accessToken;
                }
            };
    
            final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
            deviceToken = sharedPreferences.getString(GCM_TOKEN, "");
            accessToken = sharedPreferences.getString(ACCESS_TOKEN, "");
            refreshToken = sharedPreferences.getString(REFRESH_TOKEN, "");
    
            Response response = chain.proceed(request);
            boolean unauthorized =false;
            if(response.code() == 401 || response.code() == 422){
                unauthorized=true;
            }
    
            if (unauthorized) {
                tokenManager.clearToken();
                tokenManager.refreshToken();
                accessToken = sharedPreferences.getString(ACCESS_TOKEN, "");
                if(accessToken!=null){
                    modifiedRequest = request.newBuilder()
                            .addHeader("Authorization", JWT_TOKEN_PREFIX + tokenManager.getToken())
                            .build();
                    return chain.proceed(modifiedRequest);
                }
            }
            return response;
        }
    }
    

    Note : This is working code for refresh token that I have provided stay calm you just to change some constant except that it will work perfectly.Just try to understand the logic .

    In bottom there is logic to call again the same request

     if(accessToken!=null){
                    modifiedRequest = request.newBuilder()
                            .addHeader("Authorization", JWT_TOKEN_PREFIX + tokenManager.getToken())
                            .build();
                    return chain.proceed(modifiedRequest);
      }
    

提交回复
热议问题