2011-11-13 2 views
6

Je suis en train de jouer avec GAE et Android en essayant de faire une application faite pour un webservice. Je suis en train de suivre les étapes pour obtenir le jeton d'authentification de AccountManager sur Android, obtenir le cookie comme requis, puis attacher ce cookie à une requête GET que l'application GAE python gère. Pour une raison quelconque, l'application GAE ne semble pas reconnaître le cookie, ou quelque chose. Désolé pour le poste énorme, j'ai pensé que j'obtiendrais autant de code que possible pour aider à expliquer.GAE ne reconnaît pas le cookie?

J'ai cette classe de base dans GAE pour tester si l'utilisateur est reconnu.

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() 

Depuis un navigateur, cela fonctionne très bien. Je vois l'utilisateur. Lors de l'exécution sur Android, je reçois "pas d'utilisateur".

est ici un tas de code 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); 
    } 

Obtenez le jeton auth, l'invalident, et le faire à nouveau pour éviter les jetons périmés:

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); 
    } 
} 

Obtenez le cookie de l'utilisateur, stocké dans la chaîne de cookie globale.

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(); 
} 

Nous avons maintenant un cookie stocké, bouton Test enfoncé utilisateur de l'utilisateur dans l'interface, cela est exécuté:

testUser public void (Voir vue) { 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(); 
    } 

}

Voici un sniff de la connexion de 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 

La réponse ici est "Non utilisateur" de GAE. Des idées sur la façon d'obtenir GAE pour accepter et agir sur le cookie en tant qu'utilisateur? 27 secondes plus tard, je pense avoir trouvé un problème. Voici un reniflement du navigateur, je n'ai pas ce ACSID = partie.

Cookie: ACSID=AJKiYcFeUHZUP56a 

Merci pour votre aide!
Stateful

EDIT: Je l'ai corrigé. J'ai besoin d'attendre un moment pour répondre à ma propre question, pas assez de réputation. Fondamentalement, puisque je reçois le cookie avec SSL, le cookie doit être préfixé avec SACSID plutôt qu'ACSID et l'URL testuser doit également être https puisque c'est le cookie que nous utilisons.

Répondre

2

Je l'ai corrigé. Si vous envoyez la requête pour obtenir le cookie à l'aide de SSL, la réponse sera préfixée avec SACSID, sinon ACSID.

sur la requête HTTP j'ai changé l'ajout de cookie:

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

Et aussi, puisque c'est le cookie S, je dois envoyer la demande via SSL en tant que tel: