Поддержание сеанса в android (приложение остается аутентифицированным на стороне сервера)
Я создаю приложение для входа в android, в котором я нахожу URL-адрес (с именем пользователя и паролем) до этой части, он отлично работает, но после этого всякий раз, когда я нажимаю URL-адрес (после аутентификации пользователя), он ничего не возвращает (например, сообщение об ошибке, например, пожалуйста, войдите в систему). Однако он отлично работает в очень похожем приложении iphone и в браузере.
Я где-то нашел, что это ошибка phpSessionId (т.е. сеанс уничтожен для дальнейшего запроса), и если мы хотим, чтобы наше приложение Android оставалось аутентифицированным на стороне сервера, нам нужно получить этот идентификатор после первого подключения, а затем отправить это в заголовках всех наших последующих запросов.
Но проблема в том, что я не могу получить sessionId из заголовка первого соединения и отправить его с дальнейшим запросом вместе с заголовком.
Пожалуйста, дайте мне несколько кодов или ссылок, чтобы выполнить задачу должным образом.
Благодарю.
Ответы
Ответ 1
Наконец, я решил проблему обработки сеанса в Android.
Android can not обрабатывает сам сеанс (который может быть простым браузером), поэтому мы должны обрабатывать его явно.
Я немного изменил код для http-соединения.
Создал экземпляр DefaultHttpClient в первом действии, когда установлено соединение.
public static DefaultHttpClient httpClient;
Впервые подключение я сделал следующее:
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
Теперь для всех последующих подключений я использовал тот же httpClient
Например, в следующем действии:
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
Надеюсь, это поможет вам всем решить проблему сессии в Android.
Ответ 2
Лучше всего поставить всю функцию, которую ваш сервер делает в уникальном классе, который будет вызван задачами, которые хотите подключиться. Я называю этот класс WebServiceManager. Этот класс имеет тот же метод, что и сервер.
Как вам нужен уникальный сеанс:
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();
}
а затем вы вызываете метод вашего экземпляра webServiceManager для использования всегда одного и того же сеанса.:)
Ответ 3
Моя проблема заключалась в том, что я сначала зашел в систему и сохранил возвращенный сеанс в userpreferences.
После этого POST-вызов для установки записи сказал
"Ошибка, невозможно аутентифицировать пользователя"
Итак, я добавил
post.setHeader("oAuth-Token", UserPreferences.ACCESS_TOKEN);
все это выглядит так.
HttpPost post=new HttpPost(URL );
post.setHeader("oAuth-Token", UserPreferences.ACCESS_TOKEN);
.
,
и он решил проблему.
Ответ 4
Я написал сообщение об этом некоторое время назад на coderwall
Он использует классы HttpRequestInterceptor и HttpResponseInterceptor, которые идеально подходят для такого рода сценариев.
Вот пример:
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();
}
}
}
}
Ответ 5
Вот еще одна реализация, использующая библиотеку Volley... очень полезный намек от fooobar.com/info/71151/...
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
}
});
Пользовательский класс запроса
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;
}
}
Простой способ реализации волейбола с использованием одноэлементного паттерна
http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/
Не забудьте инициализировать mRequestQueue в onCreate(), чтобы избежать непредвиденного исключения нулевого указателя
@Override
public void onCreate() {
super.onCreate();
// initialize the singleton
sInstance = this;
mRequestQueue = Volley.newRequestQueue(this);
}
Надеюсь, эта помощь тоже...!:)