我正在玩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。