2017-09-29 11 views
0

mon serveur est basé sur Flask, mon client est un studio android, et je suis en communication utilisant retrofit.Authentification de Retrofit avec jeton JWT au serveur de repos

Le problème est que je ne suis pas en mesure de passer le JWT jeton correctement de l'androïde au serveur après la connexion

Avec postier, il travaille bien: {{url}}/auth - je. m se connecter en tant qu'utilisateur et obtenir le jeton JWT. Plus tard j'ajoute l'en-tête "Autorisation", avec la valeur "JWT {{jwt_token}}" et {{url}}/users/john - Je demande des informations d'utilisateur, qui est reçu sans problèmes.

Le point final du studio android:

public interface RunnerUserEndPoints { 
// @Headers("Authorization") 
    @GET("https://stackoverflow.com/users/{user}") 
    Call<RunnerUser> getUser(@Header("Authorization") String authHeader, @Path("user") String user); 

L'appel lui-même (Le access_token est correct avant de l'envoyer!):

final RunnerUserEndPoints apiService = APIClient.getClient().create(RunnerUserEndPoints.class); 
Log.i("ACCESS","Going to send get request with access token: " + access_token); 
Call<RunnerUser> call = apiService.getUser("JWT" + access_token, username); 
Log.i("DEBUG","Got call at loadData"); 
call.enqueue(new Callback<RunnerUser>() { 
    @Override 
    public void onResponse(Call<RunnerUser> call, Response<RunnerUser> response) { .... 

Le journal des erreurs de réponse du serveur:

File "C:\Users\Yonatan Bitton\RestfulEnv\lib\site-packages\flask_restful\__init__.py", line 595, in dispatch_request 
    resp = meth(*args, **kwargs) 
    File "C:\Users\Yonatan Bitton\RestfulEnv\lib\site-packages\flask_jwt\__init__.py", line 176, in decorator 
    _jwt_required(realm or current_app.config['JWT_DEFAULT_REALM']) 
    File "C:\Users\Yonatan Bitton\RestfulEnv\lib\site-packages\flask_jwt\__init__.py", line 151, in _jwt_required 
    token = _jwt.request_callback() 
    File "C:\Users\Yonatan Bitton\RestfulEnv\lib\site-packages\flask_jwt\__init__.py", line 104, in _default_request_handler 
    raise JWTError('Invalid JWT header', 'Unsupported authorization type') 
flask_jwt.JWTError: Invalid JWT header. Unsupported authorization type 
10.0.0.6 - - [30/Sep/2017 01:46:11] "GET /users/john HTTP/1.1" 500 - 

Mon api-client

public class APIClient { 
    public static final String BASE_URL = "http://10.0.0.2:8000"; 
    private static Retrofit retrofit = null; 


    public static Retrofit getClient(){ 
     if (retrofit==null){ 
      retrofit = new Retrofit.Builder().baseUrl(BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .build(); 

     } 
     Log.i("DEBUG APIClient","CREATED CLIENT"); 
     return retrofit; 
    } 
} 

En fait, je suis vraiment coincé. Je ai essayé de suivre tous les tutoriels sur le site Web de rénovation sans succès. Je suis sûr qu'il y a une solution simple, j'ai juste besoin d'ajouter "Authorization" Header avec la valeur "JWT" ​​+ access_token comme cela fonctionne dans le facteur et c'est tout! Merci.

EDIT: Le problème était la construction du access_token dans mon client. J'ai fait: JsonElement ans = response.body(). Get ("access_token"); access_token = "JWT" ​​+ ans.toString(); Ce que j'aurais dû faire: JsonElement ans = response.body(). Get ("access_token"); access_token = "JWT" ​​+ ans.getAsString();

Alors avant de l'envoyer « JWT « ey ... » » (Double « ») Et il envoie maintenant « JWT ey ... »

+0

Je suis vraiment coincé, j'ai essayé hier et aujourd'hui toute la journée .... Si vous avez une offre pour une autre mise en œuvre, je peux investir mon temps est-il, mais je dois le faire fonctionner – JohnSnowTheDeveloper

Répondre

0

Commençons à regarder ce que nous savons au sujet du problème.

  • Nous savons que la demande est envoyée
  • Nous savons que le serveur traite la demande
  • Nous savons que le JWT est invalide grâce à l'erreur:

    JWTError ('en-tête non valide JWT », 'type d'autorisation non prise en charge')

Si nous recherchons cette erreur dans le flask_jwtsource code , Nous pouvons voir que c'est là notre erreur est soulevée:

def _default_request_handler(): 
    auth_header_value = request.headers.get('Authorization', None) 
    auth_header_prefix = current_app.config['JWT_AUTH_HEADER_PREFIX'] 

    if not auth_header_value: 
     return 

    parts = auth_header_value.split() 

    if parts[0].lower() != auth_header_prefix.lower(): 
     raise JWTError('Invalid JWT header', 'Unsupported authorization type') 
    elif len(parts) == 1: 
     raise JWTError('Invalid JWT header', 'Token missing') 
    elif len(parts) > 2: 
     raise JWTError('Invalid JWT header', 'Token contains spaces') 

    return parts[1] 

Fondamentalement flask_jwt prend la valeur d'en-tête Authorization et tente de le scinder en deux.La fonction split peut diviser une chaîne par un délimiteur, mais si vous l'appelez sans un délimiteur it will use whitespace. Cela nous indique que flask_jwt attend une chaîne qui contient 2 parties séparées par des espaces, tels que l'espace, et que la première partie doit correspondre au préfixe que nous utilisons (dans ce cas JWT).

Si nous remontons et regardez votre code client, nous pouvons voir que lorsque vous construisez la valeur à mettre dans l'en-tête Authorization vous n'êtes pas ajoutez un espace entre les JWT et le jeton réel:

apiService.getUser("JWT" + access_token, username); 
Ce

est ce que vous devriez avoir fait:

apiService.getUser("JWT " + access_token, username); 

Notez l'espace après JWT?

+0

En fait, c'est l'une des premières choses que j'ai essayé – JohnSnowTheDeveloper

+0

@JohnSnowTheDeveloper Si vous obtenez toujours la même erreur, le seul autre scénario est que vous utilisez le mauvais préfixe. Avez-vous réglé 'current_app.config ['JWT_AUTH_HEADER_PREFIX']' à 'JWT'? – rzetterberg

+0

En fait c'est l'une des premières choses que j'ai essayé Essayé à nouveau maintenant: Une fois reçu et après l'authentification: JsonElement ans = response.body(). Get ("access_token"); access_token = "JWT" ​​+ ans.toString(); Ceci est le jeton envoyé: JWT "eyJ0 ..." (Je suis préoccupé par le "" peut-être?) Mais une autre erreur se produit flask_jwt.JWTError: Jeton non valide. Remboursement crypto invalide – JohnSnowTheDeveloper