管理Android应用程序cookie

时间:2013-07-30 20:39:55

标签: android http session cookies header

检查了许多类似的主题,但仍然无法找到正确的答案。

我正在尝试创建一个Android应用程序,用户登录并连接到服务器以检索一些数据。遗憾的是,我无法超越我需要应用程序维护应用程序和服务器之间的会话的部分。只是不确定如何正确地做到这一点。

据我所知,过程是这样的 - 用户点击登录按钮并发送对服务器的请求。然后收到响应,它包含带有会话ID的cookie。我将会话ID保存在SharedPreferences中供以后使用。 加载下一个活动时,我从SharedPreferences中检索此ID,将其添加到下一个HTTP请求,以便维护正确的会话。如果我错了,请纠正我。

问题在于向HTTP请求添加会话ID。在下面的代码中应该更改什么才能维护应用程序和服务器之间的会话,即使应用程序被销毁然后再打开?如何将cookie正确添加到请求中?看起来我做得不对......

我的代码如下:

public class LoginScreen extends Activity {

    DefaultHttpClient httpclient = new DefaultHttpClient();
    SharedPreferences prefs;
    Editor editor;  
    Button login_button;
    String session_cookie;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);         
        setContentView(R.layout.activity_login_screen);

        prefs = this.getSharedPreferences("filetitlehere", Context.MODE_PRIVATE);
        editor = prefs.edit();      
        session_cookie = prefs.getString("sessionid", "not saved");

        if (session_cookie != "not saved") {
            // intent to another activity
        } else {            
            login_button = (Button)findViewById(R.id.button_login);
            login_button.setOnClickListener(new View.OnClickListener() { 
               @Override
               public void onClick(View v) {
                   ConnectivityManager connMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
                   NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

                   if (networkInfo != null && networkInfo.isConnected()) {
                     new Login().execute("http://mywebpage.com/login");
                   } else {
                     // error
                   }                
               }
            });     
        }
    }

    private class Login extends AsyncTask<String, Void, String> {
        protected String doInBackground(String... url) {            
            try {
                return auth(url[0]);
            } catch (IOException e) {
                return "an error";
            }
        }       
        protected void onPostExecute(String result) {
            JSONObject jsonobj;
            Integer user_auth = 0;

            try {
                jsonobj = new JSONObject(result);
                user_auth = jsonobj.getInt("auth");             
            } catch (JSONException e) {
                // error
            }    

            if (user_auth == 0) { // in case user not logged in         
                List<Cookie> cookies = httpclient.getCookieStore().getCookies();
                for (Cookie ck : cookies) {
                    if (ck.getName() == "PHPSESSID") {
                        // saved in SharedPreferences for later use
                        prefs.edit().putString("sessionid", ck.getValue().toString()).commit();
                    }
                }
            } else {
                // user already logged in
                Intent intent = new Intent(getApplicationContext(), HomeScreen.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);  
            }
        }
    }

    private String auth(String myurl) throws IOException {      

        try {
            HttpPost httppost = new HttpPost(myurl);

            if (session_cookie == "not saved") {
                // without adding cookie, cause cookie not saved in SharedPreferences
                HttpResponse response = httpclient.execute(httppost);
            } else {
                // adding sessionid from SharedPreferences
                BasicCookieStore cstore = new BasicCookieStore();
                Cookie cookie = new BasicClientCookie("PHPSESSID",session_cookie);
                cstore.addCookie(cookie);
                HttpContext localContext = new BasicHttpContext();
                localContext.setAttribute(ClientContext.COOKIE_STORE, cstore);                          
                HttpResponse response = httpclient.execute(httppost, localContext);
            }

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuilder resp = new StringBuilder();
            String line = null;            

            while((line = bufferedReader.readLine()) != null){
                resp.append(line);
            }
            return resp.toString();

        } catch (UnsupportedEncodingException e) {
            // error  
        } catch (ClientProtocolException e) {
            // error  
        } catch (IOException e) {
            // error  
        }     
    }   
}

其他一些问题:

  • 服务器是否仅在服务器端启动“session_start()”(例如PHP)时(例如,当用户登录时)发送会话ID?
  • 如果服务器端的会话以某种方式被破坏,但我将之前保存的cookie添加到请求中该怎么办?服务器在标题中将理解和发送什么?会不会有另一个sessionid或者什么都没有?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

自从我问这个问题以来很长一段时间。我没有自己编写会话管理,而是转而使用loopj的客户端 - http://loopj.com/android-async-http

解决了一切,并且工作出色!