0
votes

I am not getting access token using retrofit2 in android client. I am trying to get access token from google OAuth2 server.I am getting auth code from my previous getAuthCode API which is successful which i checked using POSTMAN for getting access token.I am getting Not found(404) error.

D/OkHttp: <-- 404  https://www.googleapis.com/o/oauth2/token (95ms)   

Here is my okHttpClient code

public class HttpClient {
private static OkHttpClient.Builder builder;

public static synchronized OkHttpClient getOkHttpClient(){
    try {
    TrustManager[] trustManagers = new TrustManager[]{
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            }
    };

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null,trustManagers,new SecureRandom());
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder = new OkHttpClient().newBuilder()
                .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManagers[0])
                .addInterceptor(httpLoggingInterceptor)
                .hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }

    return builder.build();
}
}

Here is the Retrofit client code

public class RetrofitClient {
private static Retrofit.Builder retrofit = null;

public static Retrofit getRetrofitClient(String baseUrl){

    if(retrofit == null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(HttpClient.getOkHttpClient())
                .addConverterFactory(GsonConverterFactory.create());
    }
    return retrofit.build();
}
}

here is the interface

@POST("/o/oauth2/token")
@FormUrlEncoded
Call<AccessToken>  getAccessToken(@Field("client_id") String clientId,
                                  @Field("redirect_uri") String redirct,
                                  @Field("client_secret") String secret,
                                  @Field("grant_type") String grantType,
                                  @Field("code") String code
                                  );

And here is the calling function

AuthService authService = RetrofitClient.getRetrofitClient("https://accounts.google.com").create(AuthService.class);   
authService.getAccessToken(authCode.getOauthClientId(),redirect,clientPassword,grantType,authCode).enqueue(new Callback<AccessToken>() {
        @Override
        public void onResponse(Call<AccessToken> call, Response<AccessToken> response) {
            Log.d("AccessToken", "............." + response.isSuccessful());
            Log.d("AccessToken",response.message());
            if (response.code() == 200) {
                Log.d("Test", ".............Access Token" + response.body().getAccessToken());
            }
        }

        @Override
        public void onFailure(Call<AccessToken> call, Throwable t) {
            Log.d("Test", ".............Failed " + t.getMessage());
        }
    });

In above code i am using client_id and client_secret from console,grant_type=authorization_code,auth_code which i getting from previous API and grant_type= urn:ietf:wg:oauth:2.0:oob or only oob tried both.

What i tried

  1. Tried with same request with POSTMAN with same parameters and it was OK.
  2. Tried without redirect_uri
  3. Tried with setting Basic authentication using client id and secret

Log

D/OkHttp: --> POST https://www.googleapis.com/o/oauth2/token http/1.1
D/OkHttp: Content-Type: application/x-www-form-urlencoded
D/OkHttp: Content-Length: 221
D/OkHttp: client_id=7********-***********.apps.googleusercontent.com&redirect_uri=oob&client_secret=1-****************&grant_type=authorization_code&code=4%2Fohfz64qAyQY3K3HZc7zBplCCl4uje28RoP5fnFZwIDw
D/OkHttp: --> END POST (221-byte body)
D/OkHttp: <-- 404  https://www.googleapis.com/o/oauth2/token (79ms)
D/OkHttp: cache-control: no-cache, no-store, max-age=0, must-revalidate
D/OkHttp: pragma: no-cache
D/OkHttp: expires: Mon, 01 Jan 1990 00:00:00 GMT
D/OkHttp: date: Thu, 27 Apr 2017 08:38:54 GMT
D/OkHttp: vary: Origin
D/OkHttp: vary: X-Origin
D/OkHttp: content-type: text/html; charset=UTF-8
D/OkHttp: x-content-type-options: nosniff
D/OkHttp: x-frame-options: SAMEORIGIN
D/OkHttp: x-xss-protection: 1; mode=block
D/OkHttp: server: GSE
D/OkHttp: alt-svc: quic=":443"; ma=2592000; v="37,36,35"
D/OkHttp: Not Found
D/OkHttp: <-- END HTTP (9-byte body)
3
Lol, 404. Your url is wrong. Is not your token. If was your token, should return 401.Florescu Cătălin
no url is correct.I tried same through POSTMAN and also using DefaultHttpClient and it works.Pravin Londhe

3 Answers

1
votes

Have you tried checking Logs of your Retrofit request? for example, may be headers, request parameters or even full service URL may be different than POSTMAN request.

check below answer to enable Logging in your retrofit requests and compare request with postman: https://stackoverflow.com/a/33256827/4862126

I also found the cases when it can happen: 404: Not Found

  1. when the requested resource (with the provided ID) has never existed
  2. when accessing a API that the user can not access.

Response:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "notFound",
    "message": "Not Found"
   }
  ],
  "code": 404,
  "message": "Not Found"
 }
}
1
votes

Thanks guys for your answers. I catch my bug.To make retrofit object singleton i am checking for null and if it is not null i am returning old retrofit object.so my base URL is not changing it stick to the first time set base URL.enter image description here

0
votes

Your base URL needs to end with /, and your service entry point needs to be @POST("o/oauth2/token").