Maintaining session in android ( application stay authenticated on the server side)

后端 未结 5 1653
太阳男子
太阳男子 2020-11-29 16:29

I am building a login application in android in which i am hitting a url(with username and password) upto that part it works fine but after that whenever I am hitting a url(

相关标签:
5条回答
  • 2020-11-29 17:15

    Here is an another implementation using Volley library ... a very useful hint from 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;
        }
    
    }
    

    Simple way of implementing volley using singleton pattern http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/

    Remember to initialize mRequestQueue in onCreate() to avoid unexpected null pointer exception

    @Override
    public void onCreate() {
        super.onCreate();
    
        // initialize the singleton
        sInstance = this;
            mRequestQueue = Volley.newRequestQueue(this);
    }
    

    Hope this help too ... ! :)

    0 讨论(0)
  • 2020-11-29 17:21

    I wrote a post about it a while back on coderwall It uses the HttpRequestInterceptor and HttpResponseInterceptor classes which are perfect for that kind of scenario.

    Here is an example:

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

    }

    0 讨论(0)
  • 2020-11-29 17:30

    The best idea is to put all the function that your server do in on unique class which is going to be call by the tasks which want to connect. I call this class WebServiceManager. This class have exactly the same method than the server.

    As you want an unique session do :

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

    and then you call the method of your instance of webServiceManager to use always the same session. :)

    0 讨论(0)
  • 2020-11-29 17:31

    Finally I solved the issue of session handling in Android. Android cant handle the session itself(which a simple browser can) so we have to handle it explicitly. I changed the code for http connection a bit. Created an instance of DefaultHttpClient in the first Activity when connection established.

    public static DefaultHttpClient httpClient;
    

    For the first time connection,I did the following:

    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
    

    Now for all further connections I used the same httpClient For example in the next activity:

    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
    

    Hope this will help you all too to solve session issue in Android.

    0 讨论(0)
  • 2020-11-29 17:34

    My problem was that i login first and saved the returned session in userpreferences. After that the POST call to set a record said

    "Error ,Cannot authenticate the User"

    So i added post.setHeader("oAuth-Token", UserPreferences.ACCESS_TOKEN); the whole thing looks like this.

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

    . . and It solved the problem.

    0 讨论(0)
提交回复
热议问题