2017-09-29 13 views
0

私のサーバはFlaskベース、クライアントはアンドロイドスタジオ、私はretrofitを使った通信です。レトロフィットからJWTトークンでレストサーバへ

問題は、私はログイン後、サーバーにアンドロイドから正しくJWTトークンを渡すことができないんだということである

郵便配達で、それは良い取り組んでいます: {{URL}}/AUTH - 私は。ユーザーとしてログインし、JWTトークンを取得します。 後で、値 "JWT {{jwt_token}}"と {{url}}/users/johnの "Authorization"ヘッダーを追加しています - 問題なく受信されたユーザー情報を求めています。

アンドロイドスタジオからエンドポイント:

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

コール自体(access_tokenはを送信する前に正しいです!):

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) { .... 

サーバーからの応答エラーログ:

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 - 

My 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; 
    } 
} 

実際、私は本当に固執しています。改造のウェブサイトですべてのチュートリアルに沿って成功することなく試してみました。 シンプルな解決策があると確信しています。郵便配達員のように、値 "JWT" + access_tokenを持つ "Authorization"ヘッダーを追加するだけです。ありがとう。

EDIT: 問題は、クライアントのaccess_tokenのビルドでした。 私はしました: JsonElement ans = response.body()。get( "access_token"); access_token = "JWT" + ans.toString(); 私はどちらをすべきか: JsonElement ans = response.body()。get( "access_token"); access_token = "JWT" + ans.getAsString();だから、

それは「JWT 『EYを送っ前に...』」(ダブル「」) そして今、それは

+0

私は本当に立ち往生しています。私は昨日と今日一日中努力しています.... 別の実装のためのオファーがあれば、私は自分の時間を投資することができますが、それを働かせなければなりません – JohnSnowTheDeveloper

答えて

0

は、我々は問題について知っていることを見ていきましょう「... JWTのEY」を送信します。

JWTError( '無効なJWTヘッダ:

  • は、我々は、サーバー我々はJWTがエラーに無効おかげであることを知って
  • 要求を処理することを知っている

  • 要求が送信されることを知っています」、 『サポートされていない認証タイプ』)私たちはflask_jwtsource codeでそのエラーを探している場合

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] 

基本的flask_jwtAuthorizationヘッダの値を取り、2に分割しようとします:、私たちは、エラーが発生した場合、これがあることがわかります。関数splitは文字列を区切り文字で分割できますが、区切り文字なしで文字列を呼び出す場合はit will use whitespaceとなります。

これは、空白などで区切られた2つの部分を含む文字列と、最初の部分が使用している接頭辞(この場合はJWT)と一致する必要があることを示しています。

我々は戻って、あなたのクライアントコードを見れば、我々はあなたが値を構築しているときに、JWTと実際のトークンの間にスペースを追加しないAuthorizationヘッダーに置くことをことを見ることができます:

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

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

お知らせJWT後にスペースを:

これは、あなたがやっているはずです何ですか?

+0

実際には、私が試した最初のものの一つです – JohnSnowTheDeveloper

+0

@ JohnSnowTheDeveloperあなたはまだまったく同じエラーを取得している場合、唯一の他のシナリオは、間違った接頭辞を使用しているということです。 'current_app.config ['JWT_AUTH_HEADER_PREFIX']'を 'JWT'に設定しましたか? – rzetterberg

+0

実際にそれは私が試した最初のものの1つです もう一度試してみてください: authing後にansを受け取った後: JsonElement ans = response.body()。get( "access_token"); access_token = "JWT" + ans.toString(); これは送信されたトークンです:JWT "eyJ0 ..."(おそらく私は心配しています) しかし別のエラーが発生しました flask_jwt.JWTError:トークンが無効です。無効な暗号パッディング – JohnSnowTheDeveloper

関連する問題