Предоставляет ли Facebook iOS SDK пользователю аутентификацию каждый раз, когда они используют приложение?
Как описано в README для facebook-ios-sdk, мое приложение вызывает Facebook # authorize: delegate: перед выполнением любых вызовов API.
Этот метод требует, чтобы пользователь аутентифицировался (либо в приложении Facebook, либо в Safari), а затем отменил управление моим iPhone-приложением. Проблема заключается в том, что пользователь запрашивает аутентификацию пользователя каждый раз, когда я вызываю метод. Если они уже предоставили разрешение моему приложению, они получают сообщение о том, что приложение уже разрешено, и они должны нажать "ОК", чтобы вернуться в мое приложение. Это не выглядит очень профессионально.
У меня есть два вопроса:
-
Всегда ли пользователь должен повторно авторизоваться для совершения вызовов Facebook? Я всегда думал, что он сохранит токен доступа где-нибудь, возможно, в настройках пользователя по умолчанию, так что вам не нужно будет повторно авторизовать.
-
Если пользователю не нужно повторять авторизацию каждый раз, есть ли способ проверить, имеет ли мое приложение уже разрешение, поэтому пользователю не нужно видеть это сообщение и нажать "ОК"?
Ответы
Ответ 1
Несчастливо, что 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];
должен возвращать TRUE, указывая хорошие значения. Идите дальше и делайте вызовы 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];
}
Я использую этот код в своем приложении, и он отлично работает. Я сделал это по памяти, поэтому приношу свои извинения, если он не работает над копированием и вставкой. Там может быть какой-то туман, плюс неправильное управление памятью. Не забывайте, что токены доступа истекают, если вы не получили разрешение на офлайн. В любом случае код выше обрабатывает все.
Ответ 2
Проблема заключается в том, что пользователь запрашивает аутентифицировать каждый раз, когда я вызываю метод. Если они уже предоставили разрешение на мое приложение, они получают сообщение о том, что приложение уже разрешено, и они должны нажать "ОК" вернуться к моему приложению.
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];
}
Ответ 3
Когда пользователь войдет в систему, вы получите токен доступа и дату истечения срока действия. Сохраните токен доступа, и вы можете его повторно использовать, пока вы еще не достигли даты истечения срока действия. В SDK для Facebook есть метод для проверки: [fbConnect isSessionValid], но иногда он дает ложные срабатывания, поэтому я регистрирую пользователя, если запрос не работает.
Ответ 4
1) Нет, мне пришлось сделать Facebook *fbConnect = [[Facebook alloc] init]; [fbConnect logout:self];
, чтобы отключить сеанс пользователя.
2) Полагаю, вы могли бы назвать accestoken в Facebook.m
, чтобы проверить, что
Ответ 5
Вот более актуальный подход ответа @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)
}