GAE无法识别Cookie?

时间:2011-11-13 17:28:23

标签: android google-app-engine

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

感谢您的帮助!
有状态

编辑:我修好了。我需要等待一段时间来回答我自己的问题,但声誉不够。基本上,由于我使用SSL获取cookie,因此cookie需要以SACSID而不是ACSID为前缀,并且testuser url也需要是https,因为那是我们正在使用的cookie。

1 个答案:

答案 0 :(得分:2)

我修好了。对于任何其他人拔头发:

当您使用SSL发送获取cookie的请求时,响应将以SACSID为前缀,否则将为ACSID。

在HTTP请求上我已将cookie添加更改为:

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

而且,由于这是S cookie,我必须通过SSL发送请求: