Utrzymanie sesji w systemie android (aplikacja pozostaje uwierzytelniona po stronie serwera)

Buduję aplikację logowania w Androidzie, w której uderzam adres url (z nazwą użytkownika i hasłem) do tej części działa dobrze, ale po tym, gdy uderzam adres url (gdy użytkownik jest uwierzytelniony), nic nie zwraca (tj. komunikat o błędzie, jak Proszę się najpierw zalogować). Jednak działa dobrze w bardzo podobnej aplikacji na iphone ' a i w przeglądarce.

Doszedłem do wniosku, że jest to błąd phpSessionId(tzn. sesja jest zniszczona dla dalszego żądania) i jeśli chcemy naszego Androida aplikacja aby pozostać uwierzytelnionym po stronie serwera musimy pobrać ten identyfikator po pierwszym połączeniu, a następnie wysłać go w nagłówkach wszystkich naszych kolejnych żądań.

Ale problem polega na tym, że nie jestem w stanie pobrać sessionId z nagłówka pierwszego połączenia i wysłać go z dalszym żądaniem wraz z nagłówkiem.

Proszę o podanie kodów lub linków, aby poprawnie wykonać zadanie. Dzięki.

Author: Dinesh Sharma, 2011-05-11

5 answers

W końcu rozwiązałem problem obsługi sesji W Androidzie . Android nie może obsłużyć samej sesji(co prosta przeglądarka może), więc musimy obsłużyć go jawnie. Trochę zmieniłem kod połączenia http. Utworzono instancję DefaultHttpClient w pierwszej aktywności, gdy nawiązano połączenie.

public static DefaultHttpClient httpClient;

Po raz pierwszy zrobiłem:

URL url=new URL(urlToHit);
LoginScreen.httpClient = new DefaultHttpClient(); //LoginScreen is the name of the current Activity

HttpPost httppost = new HttpPost(url.toString());
HttpResponse response = LoginScreen.httpClient.execute(httppost); 

xr.parse(new InputSource(url.openStream())); //SAX parsing

Teraz dla wszystkich dalszych połączeń użyłem tego samego httpClient Na przykład w następnym ćwiczeniu:

URL url=new URL(urlToHit);

HttpPost httppost = new HttpPost(url.toString());
HttpResponse response = LoginScreen.httpClient.execute(httppost); 

// Log.v("response code",""+response.getStatusLine().getStatusCode());

// Get hold of the response entity
HttpEntity entity = response.getEntity();

InputStream instream = null;

if (entity != null) {
    instream = entity.getContent();
}
xr.parse(new InputSource(instream)); //SAX parsing

Mam nadzieję, że to pomoże wam wszystkim rozwiązać problem z sesją w Androidzie.

 47
Author: Dinesh Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-23 16:11:35

Najlepszym pomysłem jest umieszczenie wszystkich funkcji, które twój serwer wykonuje na unikalnej klasie, która będzie wywoływana przez zadania, które chcą się połączyć. Nazywam tę klasę WebServiceManager. Ta klasa ma dokładnie tę samą metodę niż serwer.

Jak chcesz unikalną sesję zrobić:

private static WebServiceManager wsm = null;

public static WebServiceManager getInstance() {
    if (wsm == null) {
        wsm = new WebServiceManager();
    }
    return wsm;
}

private final HttpClient httpClient;

private WebServiceManager() {
    httpClient=new DefaultHttpClient();
}

A następnie wywołujesz metodę swojej instancji webServiceManager, aby używać zawsze tej samej sesji. :)

 3
Author: Eliott Roynette,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-22 13:35:29

Mój problem polegał na tym, że najpierw zalogowałem się i zapisałem zwróconą sesję w userpreferences. Po tym wywołaniu POST, aby ustawić rekord powiedział

"Błąd, nie można uwierzytelnić użytkownika"

Więc dodałem post.setHeader("oAuth-Token", UserPreferences.ACCESS_TOKEN); całość wygląda tak.

HttpPost post=new HttpPost(URL );  
post.setHeader("oAuth-Token", UserPreferences.ACCESS_TOKEN);    

. . i to rozwiązało problem.

 1
Author: Huzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-04 07:57:25

Jakiś czas temu napisałem o tym posta na coderwall Używa klas HttpRequestInterceptor i HttpResponseInterceptor, które są idealne do tego typu scenariuszy.

Oto przykład:

public class HTTPClients {

private static DefaultHttpClient _defaultClient;
private static String session_id;
private static HTTPClients _me;
private HTTPClients() {

}
public static DefaultHttpClient getDefaultHttpClient(){
    if ( _defaultClient == null ) {
        _defaultClient = new DefaultHttpClient();
        _me = new HTTPClients();
        _defaultClient.addResponseInterceptor(_me.new SessionKeeper());
        _defaultClient.addRequestInterceptor(_me.new SessionAdder());
    }
    return _defaultClient;
}

private class SessionAdder implements HttpRequestInterceptor {

    @Override
    public void process(HttpRequest request, HttpContext context)
            throws HttpException, IOException {
        if ( session_id != null ) {
            request.setHeader("Cookie", session_id);
        }
    }

}

private class SessionKeeper implements HttpResponseInterceptor {

    @Override
    public void process(HttpResponse response, HttpContext context)
            throws HttpException, IOException {
        Header[] headers = response.getHeaders("Set-Cookie");
        if ( headers != null && headers.length == 1 ){
            session_id = headers[0].getValue();
        }
    }

}

}

 1
Author: Protostome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-02 15:18:56

Oto kolejna implementacja wykorzystująca bibliotekę Volley ... bardzo przydatna podpowiedź https://stackoverflow.com/a/36496607/3099185

    CustomRequest jsonObjReq = new CustomRequest(Request.Method.GET,
            url, null,  new Response.Listener<JSONObject>() {

        @Override
        public void onResponse(JSONObject response) {
                Log.d(TAG, response.toString());
        }
    }, new Response.ErrorListener(){

        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.d(TAG, "Error: " + error.getMessage());
            Toast.makeText(getApplicationContext(),
                    error.getMessage(), Toast.LENGTH_SHORT).show();
            // hide the progress dialog
        }
    });

Custom request class

import android.util.Log;

import com.android.volley.AuthFailureError;
import com.android.volley.Response;
import com.android.volley.toolbox.JsonObjectRequest;

import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class CustomRequest extends JsonObjectRequest {
    private String session_id = "";

    public CustomRequest(int method, String url, JSONObject jsonRequest,
                                   Response.Listener listener, Response.ErrorListener errorListener) {
        super(method, url, jsonRequest, listener, errorListener);
    }

    public CustomRequest(int method, String url, JSONObject jsonRequest, String session_id,
                                   Response.Listener listener, Response.ErrorListener errorListener) {
        super(method, url, jsonRequest, listener, errorListener);
        this.session_id = session_id;
    }


    @Override
    public Map getHeaders() throws AuthFailureError {
        Map headers = new HashMap();
        Log.d(TAG, " -> session_id = " + session_id);
        if(!(session_id.equals(""))) {
            headers.put("Cookie", this.session_id);
        }
        return headers;
    }

}

Prosty sposób implementacji woleja za pomocą wzoru Singletona http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/

Pamiętaj, aby zainicjować mRequestQueue w OnCreate (), aby uniknąć nieoczekiwanego wyjątku wskaźnika null

@Override
public void onCreate() {
    super.onCreate();

    // initialize the singleton
    sInstance = this;
        mRequestQueue = Volley.newRequestQueue(this);
}

Mam nadzieję, że to też pomoże ... ! :)

 1
Author: Bhuro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 13:48:15