2011-11-13 40 views
6

我正在玩GAE和Android試圖獲得一個爲web服務製作的應用程序。我正在完成從Android的AccountManager獲取身份驗證令牌的步驟,根據需要獲取Cookie,然後將該cookie附加到GAE python應用程序處理的GET請求。出於某種原因,GAE應用程序似乎無法識別cookie或其他內容。很抱歉,對於這個巨大的帖子,我想我會盡可能多地在代碼中幫助解釋。GAE無法識別Cookie?

我在GAE中有這個基本類來測試用戶是否被識別。

class TestUser(webapp.RequestHandler): 
    def get(self): 
    if users.get_current_user(): 
     self.response.out.write(users.get_current_user().nickname()) 
    else: 
     self.response.out.write('no user') 

application = webapp.WSGIApplication([ 
    ('/', MainPage), 
    ('/testuser', TestUser) 
], debug=True) 

def main(): 
    run_wsgi_app(application) 

if __name__ == '__main__': 
    main() 

從瀏覽器,這很好。我看到用戶。在Android上執行時,我得到「沒有用戶」。

這裏有一堆的Android代碼:

的onCreate:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     cookieLength = (TextView)findViewById(R.id.cookielength); 

     cookie = "";   

     AccountManager manager = AccountManager.get(getApplicationContext()); 
     Account[] accounts = manager.getAccountsByType("com.google"); 
     new GetAuthTokenTask().execute(accounts); 
    } 

獲得身份驗證令牌,而無效,並再次得到它,以避免過期的令牌:

private class GetAuthTokenTask extends AsyncTask<Account, Object, String> { 

    @Override 
    protected String doInBackground(Account... accounts) { 
     AccountManager manager = AccountManager.get(getApplicationContext()); 
     Account account = accounts[0]; 
     String token = this.buildToken(manager, account); 
     Log.d(TAG, "First token: "+token); 
     manager.invalidateAuthToken(account.type, token); 
     return this.buildToken(manager, account); 
    } 

    private String buildToken(AccountManager manager, Account account) { 
     try { 
      AccountManagerFuture<Bundle> future = manager.getAuthToken (account, "ah", false, null, null); 
      Bundle bundle = future.getResult(); 
      return bundle.getString(AccountManager.KEY_AUTHTOKEN); 
     } catch (OperationCanceledException e) { 
       Log.w(TAG, e.getMessage()); 
     } catch (AuthenticatorException e) { 
       Log.w(TAG, e.getMessage()); 
     } catch (IOException e) { 
       Log.w(TAG, e.getMessage()); 
     } 
     return null; 
    } 

    protected void onPostExecute(String authToken) { 
     Log.d(TAG, "Second token: "+authToken); 
     getCookie(authToken); 
    } 
} 

獲取用戶的cookie,存儲在全局cookie字符串中。

private void getCookie(final String authToken) { 
    new Thread(new Runnable() { 
     public void run() { 
      String href = "https://someawesomeapp.appspot.com/_ah/login?continue=http://localhost/&auth="+authToken; 
      Log.d(TAG, "href: "+href); 

      DefaultHttpClient httpclient = new DefaultHttpClient(); 
      final HttpParams params = new BasicHttpParams(); 
      HttpClientParams.setRedirecting(params, false); 
      httpclient.setParams(params); 
      HttpGet httpget = new HttpGet(href); 
      try { 
        HttpResponse response = httpclient.execute(httpget); 
        HttpEntity entity = response.getEntity(); 
        if (entity != null) { 
         entity.consumeContent(); 
        } 
        List<Cookie> cookies = httpclient.getCookieStore().getCookies(); 
        Log.d(TAG, "Cookies"); 
        if (cookies.isEmpty()) { 
         Log.d(TAG, "None"); 
        } else { 
         for (int i = 0; i < cookies.size(); i++) { 
          Log.d(TAG, "- " + cookies.get(i).toString()); 
          Cookie c = cookies.get(i); 
          Log.d(TAG, "cookie.getname(): "+c.getName()); 
          if (c.getName().contentEquals("SACSID")) { 
           Log.d(TAG, "Found SACSID cookie"); 
           cookie = c.getValue(); 
           Log.d(TAG, "cookie now set to: "+cookie); 
          } 
         } 
        } 
       } catch (ClientProtocolException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

     } 
    }).start(); 
} 

現在我們已經存儲cookie的時候,在用戶界面按下測試按鈕的用戶,這是執行:

公共無效爲testUser(查看視圖){ Log.d(TAG, 「爲testUser()」 );

String href = "http://someawesomeapp.appspot.com/testuser"; 


DefaultHttpClient httpclient = new DefaultHttpClient(); 
    final HttpParams params = new BasicHttpParams(); 
    HttpClientParams.setRedirecting(params, false); 
    httpclient.setParams(params); 
    HttpGet httpget = new HttpGet(href); 
    httpget.setHeader("Cookie", cookie); 
    try { 
     HttpResponse response = httpclient.execute(httpget); 
     StatusLine status = response.getStatusLine(); 
     if (status.getStatusCode() != 200) { 
      throw new IOException("Invalid response from server: " + status.toString()); 
     } 
     HttpEntity entity = response.getEntity(); 
     if (entity != null) { 
      //entity.consumeContent(); 
      InputStream inputStream = entity.getContent(); 
      ByteArrayOutputStream content = new ByteArrayOutputStream(); 

      // Read response into a buffered stream 
      int readBytes = 0; 
      byte[] sBuffer = new byte[512]; 
      while ((readBytes = inputStream.read(sBuffer)) != -1) { 
       content.write(sBuffer, 0, readBytes); 
      } 
      String dataAsString = new String(content.toByteArray()); 
      Log.d(TAG, "response: "+dataAsString); 
     } 

    } catch (ClientProtocolException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

}

下面是Wireshark的連接的一嗅:

GET /testuser HTTP/1.1 
Cookie: AJKiYcEcp6zZHFUoNU5KVlEII_wcWzlBoRQpo-KQ0T_4lwoo0znXn6t7oKpmpa7ctaVY58GO5BmwxkSZ4yZ-e7EOuwTZxeGAuKwI2YrisqjnNuQB36wuzlyBfdY6c7ECcVXuu7BNYlYJtDoB7zJDUCeSXfBmGzrfSh3fHmVO56C540aRmwZKoftRB0ejkdLB6PhUGRXcBI2rbFdvKwuNKJqB0XIr8W_zcEo9AuMjBQqXkDqDUIaGn_ehKfw9c99kzw8cJNHx1EKxVL5Tc2QIYjXWnzTJAYscITCq6IiTTNSdfzWrkbK6Ys9ZOBYNqooaAOxHM5Urx7Cgg0jo2nWQ-tNyKSHfa9Ur7IxBkp137hW7Ar5pimJYb8Jd8oZGwB4uzNHV5V5yZs9aKCqXcaQoz0wgmT5FjT-zqcGz-JfMpGTeubgPg-tQjSvhwPB6mBaXWsOOyuyZPxNeFFDh51WEv53wQs_5fdTwGQ7rQ7ZTEfoBPZNA-JNfo3ecy54DQMmhflmL_IzGE__pNToBi02WlERFm0LclPXtKm4SsDXfTfMPWAve2W1wp-mP-bwB4PljC6NP98WLPWGizRw7g2NwQ_y0iWIogIq9ag 
Host: someawesomeapp.appspot.com 
Connection: Keep-Alive 

HTTP/1.1 200 OK 
Content-Type: text/html; charset=utf-8 
Cache-Control: no-cache 
Expires: Fri, 01 Jan 1990 00:00:00 GMT 
Vary: Accept-Encoding 
Date: Sun, 13 Nov 2011 17:42:34 GMT 
Server: Google Frontend 
Transfer-Encoding: chunked 

7 
no user 
0 

這裏的反應是 「沒有用戶」 從GAE。有關如何讓GAE接受cookie並以cookie作爲用戶的任何想法?

27秒後,我想我找到了一個問題。這是來自瀏覽器的嗅探,我沒有那個ACSID =部分。

Cookie: ACSID=AJKiYcFeUHZUP56a 

感謝您的幫助!
有狀態

編輯:我弄明白了。我需要等待一段時間來回答我自己的問題,但沒有足夠的聲望。基本上,因爲我使用SSL獲取cookie,所以cookie需要以SACSID而非ACSID作爲前綴,並且testuser url也需要爲https,因爲這是我們使用的cookie。

回答

2

我弄明白了。對於任何其他人拉出他們的頭髮:

當您發送請求以使用SSL獲取Cookie時,響應將以SACSID作爲前綴,否則將爲ACSID。

在HTTP請求我已經改變了餅乾除了:

httpget.setHeader("Cookie", "SACSID="+cookie); 

而且還因爲這是在S餅乾,我必須通過SSL發送請求這樣: