Session.isOpened() == true, но Session.getAccessToken() == "" - программирование
Подтвердить что ты не робот

Session.isOpened() == true, но Session.getAccessToken() == ""

В моем приложении я пытаюсь выполнить аутентификацию (логин), передав информацию о сеансе Facebook (токен и срок действия) на мой сервер.

Моя последовательность входа на сервер приложений выглядит следующим образом:

  • Получить активную сессию facebook.
  • Если сеанс действителен, получите токен и отправьте его на сервер.

И в коде:

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

Я заметил, что внезапно, через несколько месяцев после этой работы очень просто, информация, отправляемая на сервер, иногда недействительна, в частности, token - это пустая строка, а expires - недопустимая дата.

Пройдя немного через SDK для Facebook (версия 3.0.1), я заметил, что, вероятно, является основой моей ошибки:

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

Это означает, что где-то на этом пути, SDK для Facebook создает пустой токен и возвращает его с помощью SessionState.Category.OPENED_CATEGORY.

Почему session.isOpened() возвращает true, когда на самом деле нет информации accessToken? Должен ли я проверять другое свойство? Это ошибка в SDK для Facebook?

EDIT:
Сообщено об этом в Facebook по адресу: https://developers.facebook.com/bugs/121924628017965

4b9b3361

Ответ 1

Используйте этот метод и проверьте правильность вашего хеша

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

    }
}

Ответ 2

Помимо того, что SDK для Facebook похож на магию вуду, есть кое-что, что вы делаете, чего я не делаю в своем потоке auth. Я предполагаю, что ваш фрагмент кода не находится в функции вызова Session.StatusCallback. Независимо от того, я всегда открываю сеанс для чтения, прежде чем обращаться к токену из обратного вызова. Этот запрос просто неудобно для пользователя в течение нескольких миллисекунд с загрузчиком, прежде чем он вернется. Это также помогает в случае, если пользователь удалил разрешения со своей страницы настроек Facebook.

Мой поток авторизации выглядит примерно так:

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

Ответ 3

Я решил проблему. Проблема была в ключевом хеш.

Следуйте этому руководству

перейти к шагу нет. 4 Запустите образцы.

наконец вы найдете раздел "Поиск и устранение неисправностей", и это решение.

Спасибо! https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/