2013-06-17 13 views
16

W mojej aplikacji próbuję uwierzytelnić (login) przekazując Facebook informacje sesji (żeton i data ważności) do mojego serwera.Session.isOpened() == true ale Session.getAccessToken() == „”

Moja sekwencji logowania do serwera aplikacji jest następująca:

  1. Uzyskaj aktywną sesję Facebooku.
  2. Jeśli sesja jest ważna, pobierz token i wyślij go na serwer.

I w kodzie:

Session session = Session.getActiveSession(); 
if(session != null && session.isOpened() && !didLogin) { 
    didLogin = true; 
    String token = session.getAccessToken(); 
    Date expires = session.getExpirationDate(); 
    loginWithFacebookSession(token, expires); 
} 

Zauważyłem, że nagle, po kilku miesiącach ta działa dobrze, informacje są wysyłane do serwera jest czasami nie ważne, a konkretnie token jest pusty ciąg znaków i expires jest nieprawidłową datą.

Po przejściu trochę przez SDK Facebooku (wersja 3.0.1), dostrzegłem to, co jest prawdopodobnie podstawą mojego błędu:

private static final Date MIN_DATE = new Date(Long.MIN_VALUE); 
private static final Date ALREADY_EXPIRED_EXPIRATION_TIME = MIN_DATE; 
private static final Date DEFAULT_LAST_REFRESH_TIME = new Date(); 

static AccessToken createEmptyToken(List<String> permissions) { 
    return new AccessToken("", ALREADY_EXPIRED_EXPIRATION_TIME, permissions, AccessTokenSource.NONE, 
      DEFAULT_LAST_REFRESH_TIME); 
} 

Oznacza to, że gdzieś wzdłuż sposób Facebook SDK jest tworzenie pusty token i zwrócenie go z numerem SessionState.Category.OPENED_CATEGORY.

Dlaczego session.isOpened() powrocie true podczas gdy w rzeczywistości nie ma accessToken informacji? Czy powinienem sprawdzać inną nieruchomość? Czy to błąd w SDK Facebooka?

EDIT:
zgłosiliśmy to na Facebooku: https://developers.facebook.com/bugs/121924628017965

+0

Jak się otwarcie sesji/ustawianie aktywnej sesji? –

+0

Używam klasy 'UiLifecycleHelper' zgodnie z dokumentacją [w witrynie dewelopera Facebooka] (https://developers.facebook.com/docs/tutorials/androidsdk/3.0/scrumptious/authenticate/) – thepoosh

+0

Może musisz sprawdzić, czy sesja jest w stanie OPENED_TOKEN_UPDATED, to znaczy, że token się zmienił, ale sesja jest nadal w stanie otwartym. – 5agado

Odpowiedz

1

Oprócz tego, że SDK Facebooka przypomina magię voodoo, jest coś, co robię, czego nie robię w moim autoryzowanym przepływie. Zakładam, że twój fragment kodu nie znajduje się w funkcji wywołania Session.StatusCallback. Bez względu na to, zawsze otwieram sesję do odczytu przed uzyskaniem dostępu do tokena z wywołania zwrotnego. Ta prośba po prostu przeszkadza użytkownikowi przez kilka milisekund za pomocą mechanizmu ładującego przed jego powrotem. Pomaga to również w przypadku, gdy użytkownik usunął uprawnienia z ich strony ustawień Facebooka.

Moja przepływu auth jest coś takiego:

private void startFbAuth() { 
    Session session = Session.getActiveSession(); 
    if (session == null) { 
     session = new Session(getApplicationContext()); 
     Session.setActiveSession(session); 

     Session.OpenRequest openReadRequest = new Session.OpenRequest(this); 
     openReadRequest.setPermissions(Arrays.asList({ "email" })); 
     openReadRequest.setCallback(statusCallback); 

     Session.NewPermissionsRequest permissionReadRequest = new Session.NewPermissionsRequest(this, Arrays.asList(EMAIL_PERMISSIONS)); 
     permissionReadRequest.setCallback(statusCallback); 

     if (!session.isOpened() && !session.isClosed()) { 
      session.openForRead(openReadRequest); 
     } else { 
      session.requestNewReadPermissions(permissionReadRequest); 
     } 
    } 

    private Session.StatusCallback statusCallback = new SessionStatusCallback(); 

    private class SessionStatusCallback implements Session.StatusCallback { 
     @Override 
     public void call(Session session, SessionState state, Exception exception) { 
      if (session.isClosed()) { 
       session.closeAndClearTokenInformation(); 
       Session.setActiveSession(null); 
       SessionStore.clearFacebookInformation(Activity.this); 
       // Either throw an error or try reconnecting by calling startFbAuth 
      } 
      if (exception != null) { 
       session.closeAndClearTokenInformation(); 
       Session.setActiveSession(session); 
       // Either throw an error or try reconnecting by calling startFbAuth 
      } else { 
       if (session.isOpened()) { 
        String token = session.getAccessToken(); 
        // It shouldn't be null or empty here 
       } 
      } 
     } 
    } 
+0

A co, jeśli sesja nie jest pusta, tak jak przypadek op ... Nie dostaję punktu z tym przykładem kodu ... – Renetik

2

Zastosowanie tej metody i sprawdzić, czy jest poprawny hash

public void getHashKeyForFacebook(Activity activity, String packageName){ 
    try{ 
     PackageInfo info = activity.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES); 

     for (Signature signature : info.signatures){ 
       MessageDigest md = MessageDigest.getInstance("SHA"); 
       md.update(signature.toByteArray()); 
       Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT)); 
     } 
    } catch (Exception ex){ 

    } 
} 
+0

Klucz hash był poprawny, to nie odpowiada na to pytanie, ale inne – thepoosh