Skip to content

Commit c16a7d0

Browse files
committed
Attach a nonce to Sign in with Apple requests.
1 parent 9080f99 commit c16a7d0

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

FirebaseAuthUI/Sources/FUIAuthUtils.m

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
#import "FirebaseAuthUI/Sources/Public/FirebaseAuthUI/FUIAuthUtils.h"
1818

19+
#import <CommonCrypto/CommonCrypto.h>
20+
1921
#if SWIFT_PACKAGE
2022
NSString *const FUIAuthBundleName = @"FirebaseUI_FirebaseAuthUI";
2123
#else
@@ -74,4 +76,47 @@ + (nullable UIImage *)imageNamed:(NSString *)name fromBundle:(nullable NSBundle
7476
}
7577
}
7678

79+
+ (NSString *)randomNonce {
80+
NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
81+
NSMutableString *result = [NSMutableString string];
82+
NSInteger remainingLength = 32;
83+
84+
while (remainingLength > 0) {
85+
NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16];
86+
for (NSInteger i = 0; i < 16; i++) {
87+
uint8_t random = 0;
88+
int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random);
89+
NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode);
90+
91+
[randoms addObject:@(random)];
92+
}
93+
94+
for (NSNumber *random in randoms) {
95+
if (remainingLength == 0) {
96+
break;
97+
}
98+
99+
if (random.unsignedIntValue < characterSet.length) {
100+
unichar character = [characterSet characterAtIndex:random.unsignedIntValue];
101+
[result appendFormat:@"%C", character];
102+
remainingLength--;
103+
}
104+
}
105+
}
106+
107+
return result;
108+
}
109+
110+
+ (NSString *)stringBySha256HashingString:(NSString *)input {
111+
const char *string = [input UTF8String];
112+
unsigned char result[CC_SHA256_DIGEST_LENGTH];
113+
CC_SHA256(string, (CC_LONG)strlen(string), result);
114+
115+
NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
116+
for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
117+
[hashed appendFormat:@"%02x", result[i]];
118+
}
119+
return hashed;
120+
}
121+
77122
@end

FirebaseAuthUI/Sources/Public/FirebaseAuthUI/FUIAuthUtils.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ extern NSString *const FUIAuthBundleName;
4747
*/
4848
+ (nullable UIImage *)imageNamed:(NSString *)name fromBundle:(nullable NSBundle *)bundle;
4949

50+
/** @fn randomNonce
51+
@brief Generates a random 32-character nonce.
52+
*/
53+
+ (NSString *)randomNonce;
54+
55+
/** @fn stringBySha256HashingString:
56+
@brief Generates the SHA-256 hash of the input string.
57+
@param input The input string to be hashed.
58+
*/
59+
+ (NSString *)stringBySha256HashingString:(NSString *)input;
60+
5061
@end
5162

5263
NS_ASSUME_NONNULL_END

FirebaseOAuthUI/Sources/FUIOAuth.m

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ @interface FUIOAuth () <ASAuthorizationControllerDelegate, ASAuthorizationContro
9999
*/
100100
@property(nonatomic, copy, nullable) NSString *loginHintKey;
101101

102+
@property(nonatomic, copy, nullable) NSString *currentNonce;
103+
102104
/** @property provider
103105
@brief The OAuth provider that does the actual sign in.
104106
*/
@@ -292,8 +294,11 @@ - (void)signInWithDefaultValue:(nullable NSString *)defaultValue
292294

293295
if ([self.providerID isEqualToString:@"apple.com"] && !self.authUI.isEmulatorEnabled) {
294296
if (@available(iOS 13.0, *)) {
297+
NSString *nonce = [FUIAuthUtils randomNonce];
298+
self.currentNonce = nonce;
295299
ASAuthorizationAppleIDRequest *request = [[[ASAuthorizationAppleIDProvider alloc] init] createRequest];
296300
request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
301+
request.nonce = [FUIAuthUtils stringBySha256HashingString:nonce];
297302
ASAuthorizationController* controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
298303
controller.delegate = self;
299304
controller.presentationContextProvider = self;
@@ -368,9 +373,10 @@ - (void)authorizationController:(ASAuthorizationController *)controller didCompl
368373
_providerSignInCompletion(nil, nil, nil, nil);
369374
}
370375
NSString *idToken = [[NSString alloc] initWithData:appleIDCredential.identityToken encoding:NSUTF8StringEncoding];
376+
NSString *rawNonce = self.currentNonce;
371377
FIROAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"apple.com"
372378
IDToken:idToken
373-
accessToken:nil];
379+
rawNonce:rawNonce];
374380
FIRAuthResultCallback result;
375381
NSPersonNameComponents *nameComponents = appleIDCredential.fullName;
376382
if (nameComponents != nil) {

0 commit comments

Comments
 (0)