Требует ли Facebook iOS SDK, чтобы пользователь проходил аутентификацию при каждом использовании приложения? - PullRequest
19 голосов
/ 06 апреля 2011

Как описано в README для facebook-ios-sdk, мое приложение вызывает Facebook # authorize: делегат: перед выполнением любых вызовов API.

Этот метод требует от пользователя аутентификации (либо в приложении Facebook, либо в Safari), а затем отбрасывает управление обратно в приложение iPhone. Проблема в том, что он просит пользователя проходить аутентификацию каждый раз, когда я вызываю метод. Если они уже дали разрешение на мое приложение, они получают сообщение о том, что приложение уже авторизовано, и им нужно нажать «ОК», чтобы вернуться к моему приложению. Это не выглядит очень профессионально.

Итак, у меня два вопроса:

  1. Всегда ли пользователь должен повторно авторизоваться, чтобы совершать звонки в Facebook? Я всегда думал, что это сохранит токен доступа где-нибудь, возможно, по умолчанию для пользователя, так что вам не нужно будет повторно авторизоваться.

  2. Если пользователю не нужно каждый раз повторять авторизацию, есть ли способ проверить, есть ли у моего приложения разрешение, поэтому пользователю не нужно видеть это сообщение и нажимать "ОК"?

Ответы [ 5 ]

23 голосов
/ 21 апреля 2011

К сожалению, SDK Facebook не обрабатывает это автоматически для нас. Кроме того, чтобы встроить его в SDK самостоятельно, самый простой способ таков:

Каждый раз, когда вы выделяете _facebook:

_facebook = [[Facebook alloc] initWithAppId:@"SuperDuperAppID"];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *accessToken = [prefs stringForKey:@"facebook-accessToken"];
NSString *expirationDate = [prefs stringForKey:@"facebook-expirationDate"];
_facebook.accessToken = accessToken;
_facebook.expirationDate = expirationDate;

Если вы никогда ничего не сохраняли в NSUserDefaults, тогда будут установлены значения nil. Ничего не случилось В противном случае будут установлены истинные значения, и [_facebook isSessionValid]; должен возвращать ИСТИНА, указывая на хорошие значения. Идите и делайте вызовы Facebook SDK, как будто они вошли (что они и есть). Если false, то позвоните

[facebook authorize:permissions delegate:self]; 

как обычно.

Затем убедитесь, что поддерживается следующий метод делегата Facebook:

- (void)fbDidLogin {
NSString *accessToken = _facebook.accessToken;
NSString *expirationDate = _facebook.expirationDate;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:accessToken forKey:@"facebook-accessToken"];
[prefs expirationDate forKey:@"facebook-expirationDate"];
[prefs synchronize];
}

Я использую этот код в своем приложении, и он отлично работает. Я сделал это по памяти, поэтому я прошу прощения, если это не работает на копировать и вставить. Где-то может быть опечатка, а также неправильное управление памятью. Не забывайте, что маркеры доступа истекают, если вы не получите разрешение в автономном режиме. В любом случае код выше обрабатывает все.

6 голосов
/ 22 апреля 2011

Проблема в том, что он просит пользователя проходить аутентификацию каждый раз, когда я вызываю метод.Если они уже предоставили разрешение моему приложению, они получают сообщение о том, что приложение уже авторизовано, и им нужно нажать «ОК», чтобы вернуться в мое приложение.

1) Всегда ли пользователь должен повторно авторизоватьсядля того, чтобы совершать звонки в Facebook?Я всегда думал, что это сохранит токен доступа где-нибудь, возможно, по умолчанию для пользователя, так что вам не нужно будет повторную авторизацию.

Причиной необходимости проходить процесс входа каждый раз являетсячто после успешной подписи в первый раз SDK Facebook не сохраняет маркер доступа на постоянной основе .

2) Если пользователю не нужноповторять авторизацию каждый раз, есть ли способ проверить, есть ли у моего приложения разрешение, чтобы пользователю не приходилось видеть это сообщение и нажимать «ОК»?

Тот факт, что SDK Facebook не поддерживаетсохранить маркер доступа не означает, что вы не можете сделать это самостоятельно.Следующий код иллюстрирует, как сохранить / получить токен доступа из NSUserDefaults.

-(void)login {
    // on login, use the stored access token and see if it still works
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    facebook.accessToken = [defaults objectForKey:ACCESS_TOKEN_KEY];
    facebook.expirationDate = [defaults objectForKey:EXPIRATION_DATE_KEY];

    // only authorize if the access token isn't valid
    // if it *is* valid, no need to authenticate. just move on
    if (![facebook isSessionValid]) {
        NSArray * permissions = [NSArray arrayWithObjects:@"read_stream", @"offline_access", @"email", nil];
        [facebook authorize:permissions delegate:self];
    }
}

/**
 * Called when the user has logged in successfully.
 */
- (void)fbDidLogin {
    // store the access token and expiration date to the user defaults
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:facebook.accessToken forKey:ACCESS_TOKEN_KEY];
    [defaults setObject:facebook.expirationDate forKey:EXPIRATION_DATE_KEY];
    [defaults synchronize];
}
4 голосов
/ 06 апреля 2011

Когда пользователь войдет в систему, вы получите токен доступа и срок действия. Сохраните токен доступа, и вы сможете использовать его повторно, если срок его действия еще не наступил. В SDK Facebook есть метод, позволяющий выполнить эту проверку: [fbConnect isSessionValid], но иногда он дает ложные срабатывания, поэтому я могу войти в систему в случае сбоя запроса.

2 голосов
/ 06 апреля 2011

1) Нет, мне пришлось сделать Facebook *fbConnect = [[Facebook alloc] init]; [fbConnect logout:self];, чтобы завершить сеанс пользователя

2) Я полагаю, вы могли бы вызвать accestoken в Facebook.m, чтобы проверить,

0 голосов
/ 15 января 2016

Вот более актуальный подход ответа @Daniel Amitay:
В поле зрения контроллера с кнопкой входа вы пишете

//saving user data to user defaults in order to support Facebook SSO
let token = FBSDKAccessToken.currentAccessToken()
let prefs = NSUserDefaults.standardUserDefaults()
let nsdataToken = NSKeyedArchiver.archivedDataWithRootObject(token)
prefs.setObject(nsdataToken, forKey: "facebook-AccessToken")
prefs.synchronize()

В файле AppDelegate func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool Вы пишете следующее

//restoring Facebook SSO session from user defaults
let prefs = NSUserDefaults.standardUserDefaults()
if let nsdataToken = prefs.valueForKey("facebook-AccessToken") as? NSData {
    let token = NSKeyedUnarchiver.unarchiveObjectWithData(nsdataToken) as! FBSDKAccessToken
    FBSDKAccessToken.setCurrentAccessToken(token)
}
...