2017-05-17 3 views
0

시나리오는 php-rest-api에 사용자 이름과 암호를 보내는 로그인 활동이 있고 응답이 정상이면 새로운 활동 (여기서는 테스트 활동)이 표시됩니다.갱신 기능을 사용하는 토큰 인증

그런 다음 새 활동에서 로그인 절차에서 얻은 토큰을 사용하여 데이터베이스를 갱신하여 쿼리 할 수 ​​있습니다.

문제는 다음 요청시 로그인 시도에서 쿠키를 저장해야합니다. 내가 개조 사용하고
: 2.2.0 및 을 나는 How to retrieve cookies in Retrofit?Retrofit keeps forgeting my cookies :(Android 를 읽고 나는 모든 가능한 솔루션을 확인.

내 응용 프로그램이 작동하지만 오류는 발생하지 않지만 첫 번째 및 두 번째 활동의 헤더 필드 값이 다릅니다.

: 이것은 내 테스트 활동이

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

입니다 : 이것은 내 로그인 절차가
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; } }

입니다 :

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입니다 :

내 개조 클라이언트입니다
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

포획이 계정 관리자를보세요 – AndroidSmoker74

답변

0

당신이 SharedPreferences에 토큰을 저장 시도? 토큰을 여기에 저장하는 것이 훨씬 쉽고 요청을 작성할 준비가되면 액세스 할 수 있습니다. 내가 intercepter을 사용하고 정말 잘 작동합니다.

+0

공유 환경 설정에 토큰이 있습니다. 내 문제는 두 번째 요청에서 첫 번째 요청에서 쿠키를 가져올 수 있다는 것입니다. 첫 번째 요청에서 모든 헤더를 다시 전달해야하지만, 가로 채기를 사용하면 아무 것도 발생하지 않는다고 생각합니다. – AEF

+0

토큰을 저장할 위치를 선택하십시오. 처음 요청한 후 서버가 새 토큰을 보내고있는 것으로 보입니다. 어쩌면 한 번만 설정했는지 확인할 수 있습니까? – Jlange

0

첫 번째 활동에서 얻은 토큰을 Sharedpreferences에 저장하고 아래 표시된 것처럼 사용하십시오. 두 장소에서 * * 내부의 코드는 로그인 할 때 하나의 쿠키를 받게됩니다이 조각을 시도하여 문제

*** 
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

내 의견을 바탕으로 내 게시물을 업데이트했습니다.내 첫 번째와 두 번째 헤더가 다른 것을 볼 수 있습니다. – AEF

0

안녕하세요 해결해야하며, 로그인 후 한 쿠키를 설정하고 토큰

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

관련 문제