Sajad Garshasbi
Sajad Garshasbi

Reputation: 508

HTTP request with Retrofit2 get "CLEARTEXT communication not supported" Error

i have a request in my Api interface:

@FormUrlEncoded
@POST(ApiStatics.authorizeURL)
Call<Oauth2Model> authorizer(@Field("grant_type") String grantType,
                             @Field("username") String userName,
                             @Field("password") String password,
                             @Field("client_id") String clientID,
                             @Field("client_secret") String clientSecret);

whit this getApi method:

public static MyAPI getApi() {
    if (api == null) {
        OkHttpClient client;
        if (GuildsApp.isDebug()) {
            HttpLoggingInterceptor bodyInterceptor = new HttpLoggingInterceptor();
            bodyInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            HttpLoggingInterceptor headerInterceptor = new HttpLoggingInterceptor();
            headerInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
            client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.MINUTES).writeTimeout(5, TimeUnit.MINUTES).connectTimeout(5, TimeUnit.MINUTES).addInterceptor(bodyInterceptor).addInterceptor(headerInterceptor).build();
        } else {
            client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.MINUTES).writeTimeout(5, TimeUnit.MINUTES).connectTimeout(5, TimeUnit.MINUTES).build();
        }
        Retrofit.Builder builder = new Retrofit.Builder();
        builder.baseUrl(BASE_URL);
        builder.addConverterFactory(GsonConverterFactory.create());
        builder.client(client);
        Retrofit retrofit = builder.build();
        api = retrofit.create(MyAPI.class);
    }
    return api;
}

i use this api in my fragment with this method:

private void login(String user, String pass) {
    ApiManager.getApi().authorizer("password", user, pass, ApiStatics.CID,ApiStatics.CSecret).enqueue(new Callback<Oauth2Model>() {
        @Override
        public void onResponse(Call<Oauth2Model> call, Response<Oauth2Model> response) {
            Log.e("authorize token",""+response.body().access_token);
        }

        @Override
        public void onFailure(Call<Oauth2Model> call, Throwable t) {
            Log.e("Failure ",""+t.getLocalizedMessage());
        }
    });
}

when i run project, request call onFailure method with this Log:

E/Failure: CLEARTEXT communication not supported: [ConnectionSpec(cipherSuites=[TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_3DES_EDE_CBC_SHA], tlsVersions=[TLS_1_2, TLS_1_1, TLS_1_0], supportsTlsExtensions=true), ConnectionSpec(cipherSuites=[TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_3DES_EDE_CBC_SHA], tlsVersions=[TLS_1_0], supportsTlsExtensions=true)]

my BASE_URL is HTTP , not HTTPS. my login method called with login("",""); that "" are accepted on server, how can i solve this error? i use Retrofit 2.1.0 , my test device is nexus 5x android N

Upvotes: 2

Views: 4267

Answers (3)

blacktiago
blacktiago

Reputation: 393

Try adding this to your manifest at application level

android:usesCleartextTraffic="true"

here are more details about it CLEARTEXT communication not supported on Retrofit

Upvotes: 0

RBK
RBK

Reputation: 2417

Add this annotation at the top of the class.

@PowerMockIgnore("javax.net.ssl.*")

it will ignore SSL check.

Upvotes: 2

Sajad Garshasbi
Sajad Garshasbi

Reputation: 508

by adding a simple getApi method inside my fragment instead of ApiManager, problem solved!

private MyAPI getApi(){
    Retrofit.Builder builder = new Retrofit.Builder();
    builder.baseUrl(ApiManager.BASE_URL);
    builder.addConverterFactory(GsonConverterFactory.create());
    Retrofit retrofit = builder.build();
    return retrofit.create(MyAPI.class);
}

and my login method now is:

private void login(String user, String pass) {
getApi().authorizer("password", user, pass, ApiStatics.CID,ApiStatics.CSecret).enqueue(new Callback<Oauth2Model>() {
    @Override
    public void onResponse(Call<Oauth2Model> call, Response<Oauth2Model> response) {
        Log.e("authorize token",""+response.body().access_token);
    }

    @Override
    public void onFailure(Call<Oauth2Model> call, Throwable t) {
        Log.e("Failure ",""+t.getLocalizedMessage());
    }
});
}

can some body explain to me what is difference between implementing getApi method in my ApiManager and in my fragment?

Upvotes: 1

Related Questions