2017-05-17 16 views
0

シナリオでは、ユーザ名とパスワードをphp-rest-apiに送信するログインアクティビティがあり、応答がOKなら新しいアクティビティが表示されます(ここではテストアクティビティです)。retrofitを使用したトークン認証

次に、新しいアクティビティで、ログイン手順から得たトークンを使用して、データベースを更新することができます。

問題は、次回のリクエストで使用するログイン試行からクッキーを保存する必要があることです。私は改造を使用しています
:2.2.0と を私は How to retrieve cookies in Retrofit?Retrofit keeps forgeting my cookies :(Android を読んで、私はすべての可能な解決策を確認しました。

私のアプリは動作しますが、エラーは発生しませんが、最初のアクティビティと2番目のアクティビティのヘッダーフィールドの値が異なります。

これは私の改造クライアントです:

public class RetrofitClient { 

    private static String BASE_URL = "http://192.168.0.100/rest/main.php/"; 
    private static Retrofit retrofit = null; 

    public static Retrofit getRetroftInstance() { 
     if (retrofit == null) { 

      OkHttpClient cl = new OkHttpClient().newBuilder().addInterceptor(new AuthInterceptor()).build(); 

      retrofit = new Retrofit.Builder() 
        .baseUrl(BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()) 
        // .client(client) 
        .build(); 
     } 

     return retrofit; 
    }} 

これはauthenticationinceptorです:
public class AuthInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); request = request.newBuilder() .addHeader("X-XSRF-TOKEN", ServiceSharedPrefs.getInstance().getToken()) .build(); Response response = chain.proceed(request); return response; } }

これは私のログイン手続きである:

private void loginProcedure(final String username, final String password) { 
    //Creat a user base on the user input 
    UserDB user = new UserDB(username, password); 
    //send data to the api and get response 
    Call<ApiDB> call = retrofitInterfaceObject.checkCredentials(user); 
    call.enqueue(new Callback<ApiDB>() { 
     @Override 
     public void onResponse(Call<ApiDB> call, Response<ApiDB> response) { 
      //Unauthorized handling 
      if (response.code() == 401) { 
       Toast.makeText(LoginActivity.this, "in 401", Toast.LENGTH_SHORT).show(); 
       ServiceDialog 
         .getInstance() 
         .CreateDialog(LoginActivity.this, 
           String.valueOf(response.code()) 
             + LoginActivity.this.getString(R.string.login_unauthorized_error_title) 
           , LoginActivity.this.getString(R.string.login_unauthorized_error_message) 
           , LoginActivity.this.getString(R.string.Generall_Ok_Text), null, null, null, false, false); 
      } 
      //Handling the 200 response : 2 possibility 
      else if (response.code() == 200) { 
       //if login ok 
       if (response.body().getLogin() != null) { 
        if (response.body().getLogin().contains("yes")) { 
         for(int i =0 ;i < response.headers().size();i++){ 
          Log.v("mmmm login header:"+i,response.headers().name(i)); 
         } 
         sharedPrefs.setToken(response.headers().get("X-XSRF-TOKEN")); 
         sharedPrefs.saveData(username, password); 
         LoginActivity.this.startActivity(new Intent(LoginActivity.this, test_check.class)); 
        } 

       } 
       //if login not ok 
       else if (response.body().getError().contains("Error in authentication!")) { 
        ServiceDialog 
          .getInstance() 
          .CreateDialog(LoginActivity.this, LoginActivity.this.getString(R.string.login_credentials_error_title) 
            , LoginActivity.this.getString(R.string.login_credentials_error_message) 
            , LoginActivity.this.getString(R.string.Generall_Ok_Text), null, null, null, false, false); 
       } 
      } 
      //Handle other situations 
      else { 
       ServiceDialog 
         .getInstance() 
         .CreateDialog(LoginActivity.this, response.code() + " : " + LoginActivity.this.getString(R.string.login_null_error_title) 
           , LoginActivity.this.getString(R.string.login_null_error_message) 
           , LoginActivity.this.getString(R.string.Generall_Ok_Text), null, null, null, false, false); 
      } 
     } 

     @Override 
     public void onFailure(Call<ApiDB> call, Throwable t) { 
      ServiceDialog.getInstance().CreateDialog(LoginActivity.this, LoginActivity.this.getString(R.string.login_null_error_title) 
        , t.getMessage() + "\n" + t.getLocalizedMessage(), LoginActivity.this.getString(R.string.Generall_Ok_Text), 
        null, null, null, true, true); 
     } 
    }); 

は、これは私のテストアクティビティである:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_test_check); 
    final TextView t = (TextView) findViewById(R.id.txviewtest); 

    //t.setText(ping("192.168.0.100")); 


    Call<UserDB> call = this.ret.get1(ServiceSharedPrefs.getInstance().getToken()); 
    call.enqueue(new Callback<UserDB>() { 
     @Override 
     public void onResponse(Call<UserDB> call, Response<UserDB> response) { 
      for(int i =0 ;i < response.headers().size();i++){ 
       Log.v("mmmm check header:"+i,response.headers().name(i)); 
      } 
      t.append(ServiceSharedPrefs.getInstance().getToken()); 
      t.append("\n"); 
      t.append(String.valueOf(response.code())); 
      t.append("\n"); 
      t.append(response.headers().toString()); 
      t.append("\n"); 

      t.append(response.body().toString()); 

     } 
     @Override 
     public void onFailure(Call<UserDB> call, Throwable t) { 
      ServiceDialog.getInstance().CreateDialog(test_check.this, t.getMessage(), 
        null, getString(R.string.Generall_Ok_Text), null, null, null, true, true); 
     } 
    }); 

私の最初のヘッダー:

login header:0: Date:Thu, 18 May 2017 08:10:50 GMT login header:1: Server:Apache/2.4.23 (Win64) PHP/5.6.25 login header:2: X-Powered-By:PHP/5.6.25 login header:3: Set-Cookie:XSRF-TOKEN=N18743296; path=/ login header:4: Expires:Thu, 19 Nov 1981 08:52:00 GMT login header:5: Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0 login header:6: Pragma:no-cache login header:7: Set-Cookie:XSRF-TOKEN=N18743296; path=/ login header:8: Set-Cookie:XSRF-TOKEN=N18743296; path=/ login header:9: X-XSRF-TOKEN:N18743296 login header:10: Content-Length:15 login header:11: Keep-Alive:timeout=5, max=100 login header:12: Connection:Keep-Alive login header:13: Content-Type:text/html; charset=UTF-8

私の第二のヘッダー:

second header:0: Date:Thu, 18 May 2017 08:10:50 GMT second header:1: Server:Apache/2.4.23 (Win64) PHP/5.6.25 second header:2: X-Powered-By:PHP/5.6.25 second header:3: Set-Cookie:PHPSESSID=8ol17tht32l24fblejn2mjm9d4; path=/; HttpOnly second header:4: Expires:Thu, 19 Nov 1981 08:52:00 GMT second header:5: Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0 second header:6: Pragma:no-cache second header:7: Content-Length:154 second header:8: Keep-Alive:timeout=5, max=99 second header:9: Connection:Keep-Alive second header:10: Content-Type:application/json; charset=utf-8

+0

テイクをログインした後に1がクッキーを設定します。このスニペットを試してみてくださいアカウントマネージャーを見て – AndroidSmoker74

答えて

0

はあなたがSharedPreferencesにトークンを保存しようとしたことがありますか?トークンをここに保存して、リクエストを作成する準備ができたらアクセスする方がはるかに簡単です。私はintercepterを使用し、それは本当にうまく動作します。

+0

私は自分の共有設定でトークンを持っています。私の問題は、2回目のリクエストで最初のリクエストからクッキーを取得できることです。私は最初のリクエストからすべてのヘッダーを再度渡す必要があると思いますが、インターセプトを使用することによって何も起こりません。 – AEF

+0

トークンを保存する場所を確認します。あなたの最初のリクエストの後にサーバーがあなたに新しいトークンを送信しているようです。多分それを一度しか設定しないようにしてください。 – Jlange

0

最初のアクティビティで取得したトークンをSharedpreferencesに保存し、次に示すように使用します。 2箇所* *内のコードあなたの問題を解決する必要があり

*** 
public class AuthInterceptor implements Interceptor { 

    @Override 
    public Response intercept(Chain chain) 
      throws IOException { 
     Request request = chain.request(); 
     if(prefs!=null && prefs.hasToken()){//essentially checking if the prefs has a non null token 
     request = request.newBuilder() 
       .addHeader("Authenticator", prefs.getToken()) 
       .build(); 
     } 
     Response response = chain.proceed(request); 
     return response; 
    } 
} 
*** 

retrofit = new Retrofit.Builder() 
       .baseUrl(BASE_URL) 
       .addConverterFactory(GsonConverterFactory.create()) 
       *** 
       .addInterceptor(new AuthInterceptor()) 
       //this is nota valid function.first we should ccreate a 
       //OkHttp client and add this intercept to it. 
       *** 
       // .client(client) 
       .build(); 
+0

私はこれを以前に使って、私の要求をチェックしました。リクエストに何も追加されていません。 '.addHeader(" Authenticator "、prefs.getToken())' ここで何か間違っていると私は思います。 – AEF

+0

あなたの提案に投稿ベースを更新しました。私の最初のヘッダーと2番目のヘッダーが異なることがわかります。 – AEF

0

こんにちはあなたはログインしたときに1がクッキーを受け取ることになりますし、あなたがトークン

public class RetrofitClient { 

    private static String BASE_URL = "http://192.168.0.100/rest/main.php/"; 
    private static Retrofit retrofit = null; 

    public static Retrofit getRetroftInstance() { 
     if (retrofit == null) { 

      OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); 
      httpClient.addNetworkInterceptor(new SessionRequestInterceptor()); 
      httpClient.addNetworkInterceptor(new ReceivedCookiesInterceptor()); 

      retrofit = new Retrofit.Builder() 
        .baseUrl(BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .client(httpClient.build()) 
        .build(); 
     } 

     return retrofit; 
    }} 

public class ReceivedCookiesInterceptor implements Interceptor { 

    @Override 
    public Response intercept(Chain chain) throws IOException { 
     Response originalResponse = chain.proceed(chain.request()); 

     if (!originalResponse.headers("Set-Cookie").isEmpty()) { 
      HashSet<String> cookies = new HashSet<>(); 
      for (String header : originalResponse.headers("Set-Cookie")) { 
       cookies.add(header); 
       if(header.startsWith("XSRF-TOKEN")) { 
        String newCookie[]=header.split(";"); 
        System.out.println("newCookie Length: "+newCookie.length); 
        for(String ss:newCookie) { 
         if(ss.startsWith("XSRF-TOKEN")) { 
          System.out.println("Cookies ss: " + ss); 
          sharedPrefs.setToken(ss); 
         } 
        } 
       } 
      } 
     } 
     return originalResponse; 
    } 
} 

public class SessionRequestInterceptor implements Interceptor { 

    @Override 
    public Response intercept(Chain chain) throws IOException { 
     Request original = chain.request(); 

     Request.Builder request = original.newBuilder(); 

     request.header("Cookie",ServiceSharedPrefs.getInstance().getToken())); 

     request.method(original.method(), original.body()); 

     return chain.proceed(request.build()); 
    } 

} 
+0

それは本当に助けますが、答えではありません。私はcookieManagerを使って私の問題を解決しました。ご連絡ありがとうございます – AEF

関連する問題