我正在玩GAE和Android试图获得为网络服务制作的应用程序。我正在完成从Android上的AccountManager获取身份验证令牌,根据需要获取Cookie,然后将该cookie附加到GAE python应用程序处理的GET请求的步骤。出于某种原因,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,用户在界面中按下了Test User按钮,执行:
public void testUser(View view){ 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采取行动的任何想法?
27秒后,我想我发现了一个问题。这是来自浏览器的嗅探,我没有那个ACSID = part。
Cookie: ACSID=AJKiYcFeUHZUP56a
感谢您的帮助!
有状态
答案 0 :(得分:2)
我修好了。对于任何其他人拔头发:
当您使用SSL发送获取cookie的请求时,响应将以SACSID为前缀,否则将为ACSID。
在HTTP请求上我已将cookie添加更改为:
httpget.setHeader("Cookie", "SACSID="+cookie);
而且,由于这是S cookie,我必须通过SSL发送请求: