在android中维护会话(应用程序在服务器端保持身份验证)

时间:2011-05-11 07:40:15

标签: android session http-headers session-state

我正在android中构建一个登录应用程序,我正在点击一个url(使用用户名和密码),直到该部分它工作正常,但在那之后每当我点击一个url(一旦用户通过身份验证),它就不会返回任何内容(即出现错误消息,请先登录)。但它在非常相似的iPhone应用程序和浏览器上工作正常。

我到了某处,这是phpSessionId的错误(即会话被销毁以获得进一步的请求)如果我们希望我们的Android应用程序在服务器端保持身份验证,我们需要在第一次连接后获取该ID然后发送它在我们所有后续请求的标题中。

但问题是我无法从第一个连接的标头获取sessionId,并将其与标头一起发送进一步的请求。

请给我一些代码或链接以正确完成任务。 谢谢。

4 个答案:

答案 0 :(得分:48)

最后,我解决了Android中会话处理的问题。 Android无法处理会话本身(简单的浏览器可以),因此我们必须明确处理它。 我稍微更改了http连接的代码。 建立连接时,在第一个Activity中创建 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 中的会话问题。

答案 1 :(得分:3)

最好的想法是将服务器所执行的所有功能放在将要连接的任务调用的唯一类中。我将此类称为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实例的方法来始终使用相同的会话。 :)

答案 2 :(得分:1)

我的问题是我先登录并将返回的会话保存在用户首选项中。 之后POST调用设置记录说

“错误,无法验证用户”

所以我补充道 post.setHeader("oAuth-Token", UserPreferences.ACCESS_TOKEN); 整件事看起来像这样。

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

。 。 它解决了这个问题。

答案 3 :(得分:1)

这是使用Volley库的另一个实现......来自https://stackoverflow.com/a/36496607/3099185

的非常有用的提示
ob_start();
?>
$(document).on('click', '.playVideo', function() {
    var vID = $(this).attr('data-vid');
    $('body').append('<div id="gb_video" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog modal-lg"><div class="modal-content"><div class="modal-body text-center"><div class="pad5"><button aria-label="Close" data-dismiss="modal" class="close mar10btm mar5topNeg" type="button"><span aria-hidden="true">×</span></button></div><iframe src="https://www.youtube.com/embed/'+ vID +'?rel=0&showinfo=0&hd=1&autohide=1&color=white" width="859" height="483" frameborder="0" allowfullscreen></iframe></div></div></div></div>');
    $('#gb_video').modal('show');
});
<?php
$put_in_foot_js_ready   .=  ob_get_contents();
ob_end_clean();

自定义请求类

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

使用单例模式实现凌空的简单方法 http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/

请记住在onCreate()中初始化mRequestQueue以避免意外的空指针异常

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

}

希望这也有帮助......! :)