私はGAEとAndroidを使って、Webサービス向けのアプリを手に入れようとしています。 Android上のAccountManagerからauthトークンを取得し、必要に応じてCookieを取得し、GAEのpythonアプリケーションが処理するGETリクエストにそのCookieを付加する手順を説明します。何らかの理由で、GAEアプリケーションはクッキーなどを認識していないようです。申し訳ありませんが、巨大な投稿のために、できるだけ多くのコードを説明して説明することにしました。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();
}
今は保存されたクッキーを持って、ユーザーはこれが実行され、インターフェイスでテストユーザーボタンを押す:
ます。public void 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にユーザーとしてクッキーを受け入れて行動させる方法についての考えはありますか?
27秒後に問題が見つかりました。ここではブラウザからの盗難ですが、私はそのACSID =部分を持っていません。
Cookie: ACSID=AJKiYcFeUHZUP56a
ありがとうございました!
ステートフル
EDIT:修正されました。私は自分の質問に答えるためにしばらく待つ必要があります。評判は十分ではありません。基本的には、私はSSLでクッキーを取得しているので、クッキーにはACSIDではなくSACSIDが付いていなければならず、testuserのURLはhttpsでなければなりません。