2017-02-21 1 views
2

BRIEFING AVANT « trucs techniques »
pas nouveau pour travailler avec Retrofit mais suis tombé sur ce comportement étrange que j'ai beaucoup de mal à comprendre et à corriger, J'ai deux services Web, les deux fonctionnent bien comme prévu dans Postman et iOS, mais un seul fonctionne dans Retrofit et pas l'autre,
Pour ma défense, je peux dire que je reçois réponse (non autorisée), ce qui signifie que je pouvais frapper le serveur et obtenir un résultat
Dans la défense du développeur API, il dit qu'il fonctionne dans Postman et d'autres appareils donc pas un problème de serviceObtenir 401 Unauthorized en amélioration, mais fonctionne dans Postman et Swift

Si un expert Retrofit là-bas me dire ce que le rattrapage peut faire derrière mon dos afin d'obtenir cette erreur?

TECHNIQUE STUFF
Parler du type de service, il contient Autorisation Bearer jeton en-tête qui expire toutes les 6 heures et ne contient pas params du tout (il devrait donc être facile, non?) Et simple url http://hashchuna.nn-assets.com/api/locations
Malheureusement le jeton d'en-tête ne peut pas être partagée avec une clé valide, cos it'l expiré avant que quiconque puisse l'essayer, mais ici, il est de toute façon autorisation Bearer 3d44626a55dbb024725984e0d37868336fd7e48a

que j'ai essayé
J'utilise okhttp interceptent ajouter autorisation tête à demander l'aide à la fois méthode addHeader/tête, pas d'espace dans l'url cos il r pas params
Getting 401 unauthorized error in retrofit?
Java: Android: Retrofit - using Call but, Response{code = 401,message=unauthorized}
https://github.com/square/retrofit/issues/1290
Mais non d'entre eux a aidé

AVERTISSEMENT
Maintenant, la partie la plus délicate à garder à l'esprit, le jeton quand expiré doit donner erreur 401 qui est prévu, mais le problème est même pour jeton fraîchement créé, je reçois 401, ce qui est mon problème de base

LOG

D/OkHttp: --> GET http://hashchuna.nn-assets.com/api/locations http/1.1 
D/OkHttp: Authorization: Bearer 7c0d53de006b6de931f7d8747b22442354cecef9 
D/OkHttp: --> END GET 
D/OkHttp: <-- 401 Unauthorized http://hashchuna.nn-assets.com/api/locations (773ms) 
D/OkHttp: Date: Mon, 20 Feb 2017 10:44:11 GMT 
D/OkHttp: Server: Apache 
D/OkHttp: X-Powered-By: PHP/7.0.15 
D/OkHttp: Access-Control-Allow-Origin: * 
D/OkHttp: Access-Control-Allow-Credentials: true 
D/OkHttp: Access-Control-Max-Age: 1000 
D/OkHttp: Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding 
D/OkHttp: Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT 
D/OkHttp: Expires: Thu, 19 Nov 1981 08:52:00 GMT 
D/OkHttp: Cache-Control: no-store, no-cache, must-revalidate 
D/OkHttp: Pragma: no-cache 
D/OkHttp: Set-Cookie: PHPSESSID=u477o8g0q387t92hms4nhc14n1; path=/ 
D/OkHttp: Vary: Authorization 
D/OkHttp: X-Powered-By: PleskLin 
D/OkHttp: Keep-Alive: timeout=5 
D/OkHttp: Connection: Keep-Alive 
D/OkHttp: Transfer-Encoding: chunked 
D/OkHttp: Content-Type: application/json;charset=utf-8 
D/OkHttp: <-- END HTTP 

CODE
Intercept

Request request = chain 
         .request() 
         .newBuilder() 
         //.header("Authorization","Bearer "+ SharedPrefsUtils.getSPinstance().getAccessToken(context)) 
         .addHeader("Authorization","Bearer 1ed6b7c1839e02bbf7a1b4a8dbca84d23127c68e") 
         //.addHeader("cache-control", "no-cache") 
         //.cacheControl(CacheControl.FORCE_NETWORK) 
         .build(); 

Rénovation instance

private Api getApiInstance(Context context) { 
     HttpLoggingInterceptor logInter = new HttpLoggingInterceptor(); 
     logInter.setLevel(HttpLoggingInterceptor.Level.BODY); 
     OkHttpClient mIntercepter = new OkHttpClient.Builder() 
       .addInterceptor(new RequestResponseInterseptor(context)) 
       .addInterceptor(logInter) 
       .build(); 

     Retrofit retrofitInstance = new Retrofit.Builder() 
       //.addConverterFactory(new NullOnEmptyConverterFactory()) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .baseUrl(BASE_URL) 
       .client(mIntercepter) 
       .build(); 
     return retrofitInstance.create(Api.class); 
    } 
+1

Êtes-vous ABSOLUMENT sûr que vous ajoutez un jeton mis à jour à vos en-têtes? On dirait que vous utilisez simplement un ancien jeton. – C0D3LIC1OU5

+0

@ C0D3LIC1OU5 Oui, je sais que le problème ressemble à l'erreur évidente, mais ce n'est pas, j'ai même codé en dur dès que j'ai généré un nouveau jeton, sauf si une mise en cache par mise à jour est en cours – Ujju

+0

vérifiez que les clés que vous ajoutez à l'en-tête correspondent à ce que le serveur attend et ne contiennent pas de fautes de frappe. Comme la clé "Authorization Bearer" pour la valeur de jeton (ou peu importe comment vous les appelez) – C0D3LIC1OU5

Répondre

3

SOLUTION
Merci à quelques-uns des conseils, la raison réelle pour Incompatibilités de service est, magasin de client Soi-disant POSTMAN et iOS et réutiliser COOKIE par lui-même lorsque les demandes sont sans aucun besoin pour une manipulation explicite, cookie Postman peut être testé à l'aide Postman Intercepter, mais ne peut pas être modifié car le chrome ne permet pas cookie édition par des plugins

Cependant Rénovation/OkHttp sauf indication considérera cette option désactivée (pour des raisons de sécurité peut-être),
Cookie est ajouté à l'intérieur Interseptor comme un des en-têtes addHeader("Cookie","KEY-VALUE")
ou
Utilisez cookieJar pour ajouter dans

OkHttpClient mIntercepter = new OkHttpClient.Builder() 
       .cookieJar(mCookieJar) 
       .addInterceptor(new RequestResponseInterseptor(context)) 
       .addInterceptor(logInter) 
       .build(); 

fonction de vos besoins et le type biscuit

+1

Pour votre 'mais ne peut pas être édité car le chrome ne permet pas d'éditer le cookie par des plugins', je pense que vous pouvez essayer Postman App pour Win/MacOS à https://www.getpostman.com/ – BNK

+0

Oui, je vais essayer, J'aurais pu m'avoir sauvé beaucoup de temps si j'en ai déjà eu l'occasion, .. – Ujju

2

Je pense que vous surchargez autres en-têtes Retrofit ajoute pour vous, la cause de votre API pour ne pas se soucier de votre tête Authorization. Le code ci-dessous ajoute un en-tête à vos en-têtes existants au lieu de les remplacer.

OkHttpClient mIntercepter = new OkHttpClient.Builder() 
      ... 
      .addInterceptor(new Interceptor() { 
       @Override 
       public Response intercept(Chain chain) throws IOException { 
         Request request = chain.request().newBuilder().addHeader("Authorization", "Bearer " + "1ed6b7c1839e02bbf7a1b4a8dbca84d23127c68e").build(); 
         return chain.proceed(request); 
      }) 
      ... 
      .build(); 

Format de ces en-têtes est correcte ici, la clé doit être Authorization et la valeur devrait être Bearer 1ed6b7c1839e02bbf7a1b4a8dbca84d23127c68e (dans votre cas).

+0

J'utilise Retrofit 2.1.0, à la fois 'RestAdapter' et' RequestInterceptor' a été remplacé par 'Request' et' OkHttpClient ' – Ujju

+0

Voir edit - mis à jour pour' 2.1.0' version – C0D3LIC1OU5

+0

Mais cela ressemble à mon interception droite? my 'RequestResponseInterseptor' étend' Interceptor' et crée la même requête, ,, vous pouvez vérifier mon code d'interception – Ujju

1
401 Unauthorized http://www.stackoverflow.com/api/login?email=test[email protected]&password=123456 
Date: Fri, 07 Apr 2017 11:23:28 GMT 
Server: Apache/2.4.25 (Amazon) PHP/5.6.29 
X-Powered-By: PHP/5.6.29 
Cache-Control: no-cache, private 
X-RateLimit-Limit: 60 
X-RateLimit-Remaining: 59 
Content-Length: 41 
Keep-Alive: timeout=5, max=100 
Connection: Keep-Alive 
Content-Type: application/json 
{"msg":"Invalid Credentials"} 

Je faisais face à problème comme ça va pas chercher en mesure message d'erreur.

Lorsque le serveur lancer erreur comme 401 ou une autre erreur que nous obtenons null body de server.But vous pouvez obtenir un message d'erreur de serveur dans errorBody

String response = response.errorBody().string() 
+0

Merci pour la réponse, mais mon problème n'était pas de ne pas avoir d'erreur msg, j'ai eu le errorBody très bien, dans mon cas le msg était quelque chose comme { "errors": [{"code": "bad_request", "title": "not_authorised"]]} ' – Ujju

0

Dans mon cas, malheureusement, aucun des conseils énumérés dans l » @Ujju solution n'a pas fonctionné (c.-à-d. ni l'en-tête «Cookie» ni CookieJar appliqué). La seule chose qui m'a aidé est juste le remplacement de addInterceptor à addNetworkInterceptor, et tout a commencé à fonctionner.