Retrofit and OkHttp basic authentication

后端 未结 3 1374
[愿得一人]
[愿得一人] 2020-12-12 17:24

I am trying to add basic authentication (username and password) to a Retrofit OkHttp client. This is the code I have so far:

private static Retrofit createMM         


        
相关标签:
3条回答
  • 2020-12-12 17:43

    add header interceptor

    public class HeaderInterceptor implements Interceptor {
    
        private PreferencesRepository mPrefs;
        private String mAuth;
    
        public HeaderInterceptor(PreferencesRepository p) {
            mPrefs = p;
        }
    
        @Override
        public Response intercept(Chain chain) throws IOException {
            mAuth = (mPrefs.getAuthToken() != null)?mPrefs.getAuthToken():"";
            Request r = chain.request()
                    .newBuilder()
                    .addHeader("Accept", "application/json")
                    // authorization token here
                    .addHeader("Authorization", "Bearer" + mAuth)
                    .build();
    
            return chain.proceed(r);
        }
    }
    

    add cacheinterceptor (optional)

    public class CacheInterceptor implements Interceptor {
    
        Context mContext;
    
        public CacheInterceptor(Context context) {
            this.mContext = context;
        }
    
        @Override
        public Response intercept(Chain chain) throws IOException {
    
            Request request = chain.request();
    
            if (request.method().equals("GET")) {
                if (DeviceUtils.isConnected(mContext)) {
                    request = request.newBuilder()
                            .header(Constant.CACHE_CONTROL, "only-if-cached")
                            .build();
                } else {
                    request = request.newBuilder()
                            .header(Constant.CACHE_CONTROL, "public, max-stale=2419200")
                            .build();
                }
            }
    
            Response originalResponse = chain.proceed(request);
            return originalResponse.newBuilder()
                    .header(Constant.CACHE_CONTROL, "max-age=600")
                    .build();
        }
    }
    

    implement it

    HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
    logger.setLevel(HttpLoggingInterceptor.Level.BODY);
    
    long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MiB
    Cache cache = new Cache(new File(mContext.getCacheDir(), "http"), SIZE_OF_CACHE);
    
    new OkHttpClient.Builder()
                        .addInterceptor(logger)
                        .addInterceptor(new HeaderInterceptor(u))
                        .cache(cache)
                        .addNetworkInterceptor(new CacheInterceptor(mContext))
                        .connectTimeout(Constant.CONNECTTIMEOUT, TimeUnit.SECONDS)
                        .readTimeout(Constant.READTIMEOUT, TimeUnit.SECONDS)
                        .writeTimeout(Constant.WRITETIMEOUT, TimeUnit.SECONDS)
                        .build();
    
    0 讨论(0)
  • 2020-12-12 17:54

    Find the Solution

    1.Write a Interceptor class

    import java.io.IOException;
    import okhttp3.Credentials;
    import okhttp3.Interceptor;
    import okhttp3.Request;
    import okhttp3.Response;
    
    public class BasicAuthInterceptor implements Interceptor {
    
        private String credentials;
    
        public BasicAuthInterceptor(String user, String password) {
            this.credentials = Credentials.basic(user, password);
        }
    
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Request authenticatedRequest = request.newBuilder()
                .header("Authorization", credentials).build();
            return chain.proceed(authenticatedRequest);
        }
    
    }
    

    2.Finally, add the interceptor to an OkHttp client

    OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(new BasicAuthInterceptor(username, password))
        .build();
    
    0 讨论(0)
  • 2020-12-12 17:56

    Retrofit 2

        public class ServiceGenerator {
    
        public static final String API_BASE_URL = "https://your.api-base.url";
    
        private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    
        private static Retrofit.Builder builder =
                new Retrofit.Builder()
                        .baseUrl(API_BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create());
    
        private static Retrofit retrofit = builder.build();
    
        public static <S> S createService(Class<S> serviceClass) {
            return createService(serviceClass, null, null);
        }
    
        public static <S> S createService(
                Class<S> serviceClass, String username, String password) {
            if (!TextUtils.isEmpty(username)
                    && !TextUtils.isEmpty(password)) {
                String authToken = Credentials.basic(username, password);
                return createService(serviceClass, authToken);
            }
    
            return createService(serviceClass, null);
        }
    
        public static <S> S createService(
                Class<S> serviceClass, final String authToken) {
            if (!TextUtils.isEmpty(authToken)) {
                AuthenticationInterceptor interceptor =
                        new AuthenticationInterceptor(authToken);
    
                if (!httpClient.interceptors().contains(interceptor)) {
                    httpClient.addInterceptor(interceptor);
    
                    builder.client(httpClient.build());
                    retrofit = builder.build();
                }
            }
    
            return retrofit.create(serviceClass);
        }
    }
    

    Retrofit 1.9

    public class ServiceGenerator {
    
        public static final String API_BASE_URL = "https://your.api-base.url";
    
        private static RestAdapter.Builder builder = new RestAdapter.Builder()
                    .setEndpoint(API_BASE_URL)
                    .setClient(new OkClient(new OkHttpClient()));
    
        public static <S> S createService(Class<S> serviceClass) {
            return createService(serviceClass, null, null);
        }
    
        public static <S> S createService(Class<S> serviceClass, String username, String password) {
            if (username != null && password != null) {
                // concatenate username and password with colon for authentication
                String credentials = username + ":" + password;
                // create Base64 encodet string
                final String basic =
                        "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
    
                builder.setRequestInterceptor(new RequestInterceptor() {
                    @Override
                    public void intercept(RequestFacade request) {
                        request.addHeader("Authorization", basic);
                        request.addHeader("Accept", "application/json");
                    }
                });
            }
    
            RestAdapter adapter = builder.build();
            return adapter.create(serviceClass);
        }
    }
    

    AuthenticationInterceptor.java

        public class AuthenticationInterceptor implements Interceptor {
    
        private String authToken;
    
        public AuthenticationInterceptor(String token) {
            this.authToken = token;
        }
    
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();
    
            Request.Builder builder = original.newBuilder()
                    .header("Authorization", authToken);
    
            Request request = builder.build();
            return chain.proceed(request);
        }
    }
    

    Usage

    Retrofit 2

    Interface

    public interface LoginService {  
        @POST("/login")
        Call<User> basicLogin();
    }
    

    Requester

    LoginService loginService =  
       ServiceGenerator.createService(LoginService.class, "user", "secretpassword");
    Call<User> call = loginService.basicLogin();  
    call.enqueue(new Callback<User >() {  
        @Override
        public void onResponse(Call<User> call, Response<User> response) {
            if (response.isSuccessful()) {
                // user object available
            } else {
                // error response, no access to resource?
            }
        }
    
        @Override
        public void onFailure(Call<User> call, Throwable t) {
            // something went completely south (like no internet connection)
            Log.d("Error", t.getMessage());
        }
    }
    

    Retrofit 1.9

    Interface

    public interface LoginService {  
        @POST("/login")
        void basicLogin(Callback<User> cb);
    }
    

    Requester

    LoginService loginService =  
        ServiceGenerator.createService(LoginService.class, "user", "secretpassword");
    loginService.basicLogin(new Callback<User>() {  
        @Override
        public void success(User user, Response response) {
            // user object available
        }
    
        @Override
        public void failure(RetrofitError error) {
            // handle errors, too
        }
    });
    

    More information see here.

    0 讨论(0)
提交回复
热议问题