@@ -68,6 +68,11 @@ @interface FUIFacebookAuth () <FUIAuthProvider>
68
68
*/
69
69
@property (nonatomic , strong ) FIROAuthProvider *providerForEmulator;
70
70
71
+ /* * @property currentNonce
72
+ @brief The nonce for the current Facebook Limited Login session, if any.
73
+ */
74
+ @property (nonatomic , copy , nullable ) NSString *currentNonce;
75
+
71
76
@end
72
77
73
78
@implementation FUIFacebookAuth {
@@ -131,6 +136,9 @@ - (nullable NSString *)providerID {
131
136
return FIRFacebookAuthProviderID;
132
137
}
133
138
139
+ /* * @fn accessToken:
140
+ @brief The access token provided by Facebook's login flow.
141
+ */
134
142
- (nullable NSString *)accessToken {
135
143
if (self.authUI .isEmulatorEnabled ) {
136
144
return nil ;
@@ -139,10 +147,13 @@ - (nullable NSString *)accessToken {
139
147
}
140
148
141
149
/* * @fn idToken:
142
- @brief Facebook doesn't provide User Id Token during sign in flow
150
+ @brief The ID token provided by Facebook's login flow.
143
151
*/
144
152
- (nullable NSString *)idToken {
145
- return nil ;
153
+ if (self.authUI .isEmulatorEnabled ) {
154
+ return nil ;
155
+ }
156
+ return FBSDKAuthenticationToken.currentAuthenticationToken .tokenString ;
146
157
}
147
158
148
159
- (NSString *)shortName {
@@ -191,29 +202,45 @@ - (void)signInWithDefaultValue:(nullable NSString *)defaultValue
191
202
return ;
192
203
}
193
204
194
- [_loginManager logInWithPermissions: _scopes
195
- fromViewController: presentingViewController
196
- handler: ^(FBSDKLoginManagerLoginResult *result,
197
- NSError *error) {
198
- if (error) {
199
- NSError *newError =
200
- [FUIAuthErrorUtils providerErrorWithUnderlyingError: error
201
- providerID: FIRFacebookAuthProviderID];
202
- [self completeSignInFlowWithAccessToken: nil error: newError];
203
- } else if (result.isCancelled ) {
204
- NSError *newError = [FUIAuthErrorUtils userCancelledSignInError ];
205
- [self completeSignInFlowWithAccessToken: nil error: newError];
206
- } else {
205
+ if (self.useLimitedLogin ) {
206
+ // Facebook Limited Login
207
+ NSString *nonce = [FUIAuthUtils randomNonce ];
208
+ self.currentNonce = nonce;
209
+ FBSDKLoginConfiguration *configuration =
210
+ [[FBSDKLoginConfiguration alloc ] initWithPermissions: _scopes
211
+ tracking: FBSDKLoginTrackingLimited
212
+ nonce: [FUIAuthUtils stringBySHA256HashingString: nonce]];
213
+ [_loginManager logInFromViewController: presentingViewController
214
+ configuration: configuration
215
+ completion: ^(FBSDKLoginManagerLoginResult *result, NSError *error) {
216
+ if ([self maybeHandleCancelledResult: result error: error]) {
217
+ return ;
218
+ }
219
+ self->_email = FBSDKProfile.currentProfile .email ;
220
+ NSString *idToken = FBSDKAuthenticationToken.currentAuthenticationToken .tokenString ;
221
+ [self completeSignInFlowWithAccessToken: nil idToken: idToken error: nil ];
222
+ }];
223
+ } else {
224
+ [_loginManager logInWithPermissions: _scopes
225
+ fromViewController: presentingViewController
226
+ handler: ^(FBSDKLoginManagerLoginResult *result,
227
+ NSError *error) {
228
+ if ([self maybeHandleCancelledResult: result error: error]) {
229
+ return ;
230
+ }
207
231
// Retrieve email.
208
- [[[FBSDKGraphRequest alloc ] initWithGraphPath: @" me" parameters: @{ @" fields" : @" email" }] startWithCompletion: ^(id <FBSDKGraphRequestConnecting> connection,
209
- id result,
210
- NSError *error) {
232
+ [[[FBSDKGraphRequest alloc ] initWithGraphPath: @" me"
233
+ parameters: @{ @" fields" : @" email" }]
234
+ startWithCompletion: ^(id <FBSDKGraphRequestConnecting> connection,
235
+ id result,
236
+ NSError *error) {
211
237
self->_email = result[@" email" ];
212
238
}];
213
239
[self completeSignInFlowWithAccessToken: result.token.tokenString
240
+ idToken: nil
214
241
error: nil ];
215
- }
216
- }];
242
+ }];
243
+ }
217
244
}
218
245
219
246
- (void )signInWithOAuthProvider : (FIROAuthProvider *)oauthProvider
@@ -269,21 +296,31 @@ - (BOOL)handleOpenURL:(NSURL *)URL sourceApplication:(NSString *)sourceApplicati
269
296
270
297
#pragma mark -
271
298
272
- /* * @fn completeSignInFlowWithAccessToken:error:
299
+ /* * @fn completeSignInFlowWithAccessToken:idToken: error:
273
300
@brief Called with the result of a Facebook sign-in attempt. Invokes and clears any pending
274
301
sign in callback block.
275
- @param accessToken The Facebook access token, if successful.
302
+ @param accessToken The Facebook access token, if the Facebook sign-in attempt with tracking enabled is successful.
303
+ @param idToken The Facebook ID token, if the Facebook Limited Login attempt is successful.
276
304
@param error An error which occurred during the sign-in attempt.
277
305
*/
278
306
- (void )completeSignInFlowWithAccessToken : (nullable NSString *)accessToken
307
+ idToken : (nullable NSString *)idToken
279
308
error : (nullable NSError *)error {
280
309
if (error) {
281
310
[self callbackWithCredential: nil error: error result: nil ];
282
311
return ;
283
312
}
284
- // Assume accessToken cannot be nil if there's no error.
285
- NSString *_Nonnull token = (id _Nonnull)accessToken;
286
- FIRAuthCredential *credential = [FIRFacebookAuthProvider credentialWithAccessToken: token];
313
+ FIRAuthCredential *credential;
314
+ if (idToken) {
315
+ NSString *rawNonce = self.currentNonce ;
316
+ credential = [FIROAuthProvider credentialWithProviderID: FIRFacebookAuthProviderID
317
+ IDToken: idToken
318
+ rawNonce: rawNonce];
319
+ } else {
320
+ // Assume accessToken cannot be nil if there's no error and idToken is nil.
321
+ NSString *_Nonnull token = (id _Nonnull)accessToken;
322
+ credential = [FIRFacebookAuthProvider credentialWithAccessToken: token];
323
+ }
287
324
UIActivityIndicatorView *activityView =
288
325
[FUIAuthBaseViewController addActivityIndicator: _presentingViewController.view];
289
326
[activityView startAnimating ];
@@ -347,4 +384,22 @@ - (FBSDKLoginManager *)createLoginManager {
347
384
return [[FBSDKLoginManager alloc ] init ];
348
385
}
349
386
387
+ - (BOOL )maybeHandleCancelledResult : (FBSDKLoginManagerLoginResult *)result
388
+ error : (NSError *)error {
389
+ if (error) {
390
+ NSError *newError =
391
+ [FUIAuthErrorUtils providerErrorWithUnderlyingError: error
392
+ providerID: FIRFacebookAuthProviderID];
393
+ [self completeSignInFlowWithAccessToken: nil idToken: nil error: newError];
394
+ return true ;
395
+ }
396
+
397
+ if (result.isCancelled ) {
398
+ NSError *newError = [FUIAuthErrorUtils userCancelledSignInError ];
399
+ [self completeSignInFlowWithAccessToken: nil idToken: nil error: newError];
400
+ return true ;
401
+ }
402
+ return false ;
403
+ }
404
+
350
405
@end
0 commit comments