Limited Login for iOS

Limited Login allows developers to signal that a login is limited in terms of tracking users.

What to Expect

A successful login attempt will populate a global AuthenticationToken instance that provides information about the login attempt that can be used to verify the authentication on the client’s servers. Additionally, we will populate a shared Profile instance that will contain basic information including an app-scoped ID for the user, the user's name, and profile picture.

Permissions

The available permissions you can request are the following:

  • public_profile
  • email
  • gaming_profile
  • gaming_user_picture
  • user_age_range
  • user_birthday
  • user_friends
  • user_gender
  • user_hometown
  • user_link
  • user_location
  • user_messenger_contact

Custom Nonces

Limited Login allows developers to pass a nonce for use in verifying an authentication attempt on their servers. For information on using the nonce to validate tokens, see Validating the Limited Login OIDC Token.

Limitations

App switch, in which the login dialog is presented to the user in the Facebook for iOS app when they are already logged in there, is not supported for limited login flows.

New API Elements

The Facebook SDK for iOS provides a new FBSDKLoginTracking enumeration. The possible values are enabled and limited. For Limited Login, use limited.

enum LoginTracking {
    case enabled
    case limited
}
typedef NS_ENUM(NSUInteger, FBSDKLoginTracking)
{
  FBSDKLoginTrackingEnabled,
  FBSDKLoginTrackingLimited,
} NS_SWIFT_NAME(LoginTracking);

In addition, Limited Login uses FBSDKLoginConfiguration to modify the default behavior of a login attempt. This configuration be created with default properties, explicit properties (Swift only), or with one of several initializers:

init?(
    permissions: Set<Permission> = [],
    tracking: LoginTracking = .enabled,
    nonce: String = UUID().uuidString
)
initWithPermissions:(NSArray\<NSString *> *)permissions                                                          
           tracking:(FBSDKLoginTracking)tracking
              nonce:(NSString *)nonce

Properties

PropertyDescription

requestedPermissions: Set<Permissions> (Swift)

Requested permissions for the login attempt. Defaults to an empty set.

requestedPermissions: Set<String> (ObjC)

Requested permissions for the login attempt. Defaults to an empty set.

tracking: LoginTracking

Login tracking preference. Defaults to .enabled.

nonce: String

Nonce that the configuration was created with. A unique nonce will be used if none is provided to the factory method.

Trying to create a configuration fails if the following conditions are not met:

  • Nonce must be a non-empty string that does not include whitespace.

  • You cannot request permissions that are out of the scope of the tracking. For example, requesting user_likes does not work if the tracking is .limited.

  • For the permissions you can request, see the Permissions section.

Implement Limited Login

To implement Limited Login in your app using the login manager class directly, upgrade to the latest Facebook SDK for iOS and use the following code:

let loginManager = LoginManager()

// Ensure the configuration object is valid
guard let configuration = LoginConfiguration(
	permissions:["email", "user_friends", "user_birthday", "user_age_range", "user_gender", "user_location", "user_hometown", "user_link"],  
	tracking: .limited,
	nonce: "123"
) 
else {
    return
}

loginManager.logIn(configuration: configuration) { result in
    switch result {
    case .cancelled, .failed:
        // Handle error
        break
    case .success:
        // getting user ID
        let userID = Profile.current?.userID

        // getting pre-populated email
        let email = Profile.current?.email

        // getting pre-populated friends list
        let friendIDs = Profile.current?.friendIDs

        // getting pre-populated user birthday
        let birthday = Profile.current?.birthday

        // getting pre-populated age range
        let ageRange = Profile.current?.ageRange

        // getting user gender
        let gender = Profile.current?.gender
  
        // getting user location
        let location = Profile.current?.location
  
        // getting user hometown
        let hometown = Profile.current?.hometown
  
        // getting user profile URL
        let profileURL = Profile.current?.linkURL
  
        // getting id token string
        let tokenString = AuthenticationToken.current?.tokenString
    }
}
FBSDKLoginManager *loginManager = [FBSDKLoginManager new];
FBSDKLoginConfiguration *configuration =
  [[FBSDKLoginConfiguration alloc] initWithPermissions:@[@"email", @"user_friends", @"user_birthday", @"user_age_range", @"user_hometown", @"user_location", @"user_gender", @"user_link"]
                                              tracking:FBSDKLoginTrackingLimited
                                                 nonce:@"123"];
[loginManager logInFromViewController:self
                        configuration:configuration
                           completion:^(FBSDKLoginManagerLoginResult * result, NSError *error) {
  if (!error && !result.isCancelled) {
    // Login successful

    // getting user ID
    NSString *userID =
      FBSDKProfile.currentProfile.userID;

    // getting id token string
    NSString *idTokenString =
      FBSDKAuthenticationToken.currentAuthenticationToken.tokenString;

    // fetching pre-populated email
    NSString *email = FBSDKProfile.currentProfile.email;
  
    // getting pre-populated friends list
    NSArray<FBSDKUserIdentifier *> *friendIDs = FBSDKProfile.currentProfile.friendIDs;

    // getting pre-populated user birthday
    NSDate *birthday = FBSDKProfile.currentProfile.birthday;

    // getting pre-populated age range
    FBSDKUserAgeRange *ageRange = FBSDKProfile.currentProfile.ageRange;  
  
    // getting pre-populated age range
    FBSDKLocation *hometown = FBSDKProfile.currentProfile.hometown;  
  
    // getting pre-populated age range
    FBSDKLocation *location = FBSDKProfile.currentProfile.location;  
  
    // getting pre-populated age range
    NSString *gender = FBSDKProfile.currentProfile.gender;  
  
    // getting pre-populated age range
    NSURL *userLink = FBSDKProfile.currentProfile.linkURL;  
  }
}];

To implement Limited Login in your app using the login button, upgrade to the latest Facebook SDK for iOS and use the following code:

override func viewDidLoad() {
    super.viewDidLoad()

    setupLoginButton()
}
  
func setupLoginButton() {
    loginButton.delegate = self
    
    loginButton.permissions = ["email"]
    loginButton.loginTracking = .limited
    loginButton.nonce = "123" as NSString
}

func loginButton(
    _ loginButton: FBLoginButton,
    didCompleteWith potentialResult: LoginManagerLoginResult?,
    error potentialError: Error?
) {
    if let error = potentialError {
        // Handle Error
    }

    guard let result = potentialResult else {
        // Handle missing result  
    }
        
    guard !result.isCancelled else {
        // Handle cancellation
    }

    // Handle successful login
  
    let userID = Profile.current?.userID
    let email = Profile.current?.email
    let tokenString = AuthenticationToken.current?.tokenString
}
- (void)viewDidLoad
{
  [super viewDidLoad];

  [self setupLoginButton];
}
  
- (void)setupLoginButton
{
  self.loginButton.delegate = self;  
  self.loginButton.permissions = @[@"email"]
  self.loginButton.loginTracking = FBSDKLoginTrackingLimited
  self.loginButton.nonce = @"123"
}

- (void)    loginButton:(FBSDKLoginButton *)loginButton
  didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result
                  error:(NSError *)error
{
  if (error) {
    // Handle error
  }

  if (result && result.isCancelled) {
    // Handle cancellation
  }

  // Handle success
}