Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge App check auth integration into master branch #11056

Merged
merged 6 commits into from
Apr 1, 2023
2 changes: 2 additions & 0 deletions FirebaseAuth.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ supports email and password accounts, as well as several 3rd party authenticatio
source + '**/*.[mh]',
'FirebaseCore/Extension/*.h',
'FirebaseAuth/Interop/*.h',
'FirebaseAppCheck/Interop/*.h',
]
s.public_header_files = source + 'Public/FirebaseAuth/*.h'
s.preserve_paths = [
Expand All @@ -51,6 +52,7 @@ supports email and password accounts, as well as several 3rd party authenticatio
}
s.framework = 'Security'
s.ios.framework = 'SafariServices'
s.dependency 'FirebaseAppCheckInterop', '~> 10.0'
s.dependency 'FirebaseCore', '~> 10.0'
s.dependency 'GoogleUtilities/AppDelegateSwizzler', '~> 7.8'
s.dependency 'GoogleUtilities/Environment', '~> 7.8'
Expand Down
3 changes: 3 additions & 0 deletions FirebaseAuth/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#Unrealeased
- [feature] Added Firebase App Check support to Firebase Auth.

# 10.7.0
- [added] Added an API for developers to pass the fullName from the Sign in with Apple credential to Firebase. (#10068)

Expand Down
12 changes: 8 additions & 4 deletions FirebaseAuth/Sources/Auth/FIRAuth.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FirebaseAuth.h"
#import "FirebaseCore/Extension/FirebaseCoreInternal.h"

#import "FirebaseAppCheck/Interop/FIRAppCheckInterop.h"
#import "FirebaseAuth/Sources/Auth/FIRAuthDataResult_Internal.h"
#import "FirebaseAuth/Sources/Auth/FIRAuthDispatcher.h"
#import "FirebaseAuth/Sources/Auth/FIRAuthGlobalWorkQueue.h"
Expand Down Expand Up @@ -462,7 +463,8 @@ - (instancetype)initWithApp:(FIRApp *)app {
self = [self initWithAPIKey:app.options.APIKey
appName:app.name
appID:app.options.googleAppID
heartbeatLogger:app.heartbeatLogger];
heartbeatLogger:app.heartbeatLogger
appCheck:FIR_COMPONENT(FIRAppCheckInterop, app.container)];
if (self) {
_app = app;
#if TARGET_OS_IOS
Expand All @@ -475,20 +477,22 @@ - (instancetype)initWithApp:(FIRApp *)app {
- (nullable instancetype)initWithAPIKey:(NSString *)APIKey
appName:(NSString *)appName
appID:(NSString *)appID {
return [self initWithAPIKey:APIKey appName:appName appID:appID heartbeatLogger:nil];
return [self initWithAPIKey:APIKey appName:appName appID:appID heartbeatLogger:nil appCheck:nil];
}

- (nullable instancetype)initWithAPIKey:(NSString *)APIKey
appName:(NSString *)appName
appID:(NSString *)appID
heartbeatLogger:(nullable id<FIRHeartbeatLoggerProtocol>)heartbeatLogger {
heartbeatLogger:(nullable id<FIRHeartbeatLoggerProtocol>)heartbeatLogger
appCheck:(nullable id<FIRAppCheckInterop>)appCheck {
self = [super init];
if (self) {
_listenerHandles = [NSMutableArray array];
_requestConfiguration = [[FIRAuthRequestConfiguration alloc] initWithAPIKey:APIKey
appID:appID
auth:self
heartbeatLogger:heartbeatLogger];
heartbeatLogger:heartbeatLogger
appCheck:appCheck];
_firebaseAppName = [appName copy];
#if TARGET_OS_IOS
_settings = [[FIRAuthSettings alloc] init];
Expand Down
49 changes: 39 additions & 10 deletions FirebaseAuth/Sources/AuthProvider/OAuth/FIROAuthProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIROAuthCredential.h"
#import "FirebaseCore/Extension/FirebaseCoreInternal.h"

#import "FirebaseAppCheck/Interop/FIRAppCheckTokenResultInterop.h"
#import "FirebaseAuth/Sources/Auth/FIRAuthGlobalWorkQueue.h"
#import "FirebaseAuth/Sources/Auth/FIRAuth_Internal.h"
#import "FirebaseAuth/Sources/AuthProvider/OAuth/FIROAuthCredential_Internal.h"
Expand Down Expand Up @@ -325,6 +326,8 @@ - (void)getHeadFulLiteURLWithEventID:(NSString *)eventID
NSString *apiKey =
strongSelf->_auth.requestConfiguration.APIKey;
NSString *tenantID = strongSelf->_auth.tenantID;
id<FIRAppCheckInterop> appCheck =
strongSelf->_auth.requestConfiguration.appCheck;
NSMutableDictionary *urlArguments = [@{
@"apiKey" : apiKey,
@"authType" : kAuthTypeSignInWithRedirect,
Expand Down Expand Up @@ -361,6 +364,7 @@ - (void)getHeadFulLiteURLWithEventID:(NSString *)eventID
urlArguments[@"hl"] =
strongSelf->_auth.requestConfiguration.languageCode;
}

NSString *argumentsString = [strongSelf
httpArgumentsStringForArgsDictionary:urlArguments];
NSString *URLString;
Expand All @@ -374,16 +378,41 @@ - (void)getHeadFulLiteURLWithEventID:(NSString *)eventID
[NSString stringWithFormat:kHeadfulLiteURLStringFormat,
authDomain, argumentsString];
}
if (completion) {
NSCharacterSet *set =
[NSCharacterSet URLFragmentAllowedCharacterSet];
completion(
[NSURL
URLWithString:
[URLString
stringByAddingPercentEncodingWithAllowedCharacters:
set]],
nil);
NSCharacterSet *set =
[NSCharacterSet URLFragmentAllowedCharacterSet];
NSURLComponents *components = [[NSURLComponents alloc]
initWithString:
[URLString
stringByAddingPercentEncodingWithAllowedCharacters:
set]];
if (appCheck) {
[appCheck
getTokenForcingRefresh:false
completion:^(
id<FIRAppCheckTokenResultInterop> _Nonnull tokenResult) {
if (tokenResult.error) {
FIRLogWarning(
kFIRLoggerAuth, @"I-AUT000018",
@"Error getting App Check token; "
@"using placeholder token "
@"instead. Error: %@",
tokenResult.error);
}
NSString *appCheckTokenFragment = [@"fac="
stringByAppendingString:tokenResult
.token];
[components
setFragment:appCheckTokenFragment];

if (completion) {
completion([components URL], nil);
}
}];

} else {
if (completion) {
completion([components URL], nil);
}
}
}];
}
Expand Down
33 changes: 30 additions & 3 deletions FirebaseAuth/Sources/AuthProvider/Phone/FIRPhoneAuthProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIRPhoneAuthProvider.h"
#import "FirebaseCore/Extension/FirebaseCoreInternal.h"

#import "FirebaseAppCheck/Interop/FIRAppCheckTokenResultInterop.h"
#import "FirebaseAuth/Sources/Auth/FIRAuthGlobalWorkQueue.h"
#import "FirebaseAuth/Sources/Auth/FIRAuth_Internal.h"
#import "FirebaseAuth/Sources/Backend/FIRAuthBackend+MultiFactor.h"
Expand Down Expand Up @@ -718,6 +719,9 @@ - (void)reCAPTCHAURLWithEventID:(NSString *)eventID completion:(FIRReCAPTCHAURLC
NSString *clientID = self->_auth.app.options.clientID;
NSString *appID = self->_auth.app.options.googleAppID;
NSString *apiKey = self->_auth.requestConfiguration.APIKey;
id<FIRAppCheckInterop> appCheck =
self->_auth.requestConfiguration.appCheck;

NSMutableArray<NSURLQueryItem *> *queryItems = [@[
[NSURLQueryItem queryItemWithName:@"apiKey" value:apiKey],
[NSURLQueryItem queryItemWithName:@"authType"
Expand All @@ -738,7 +742,6 @@ - (void)reCAPTCHAURLWithEventID:(NSString *)eventID completion:(FIRReCAPTCHAURLC
addObject:[NSURLQueryItem queryItemWithName:@"appId"
value:appID]];
}

if (self->_auth.requestConfiguration.languageCode) {
[queryItems
addObject:[NSURLQueryItem
Expand All @@ -752,8 +755,32 @@ - (void)reCAPTCHAURLWithEventID:(NSString *)eventID completion:(FIRReCAPTCHAURLC
[NSString stringWithFormat:kReCAPTCHAURLStringFormat,
authDomain]];
[components setQueryItems:queryItems];
if (completion) {
completion([components URL], nil);
if (appCheck) {
[appCheck
getTokenForcingRefresh:false
completion:^(
id<FIRAppCheckTokenResultInterop> _Nonnull tokenResult) {
if (tokenResult.error) {
FIRLogWarning(
kFIRLoggerAuth, @"I-AUT000018",
@"Error getting App Check token; "
@"using placeholder token "
@"instead. Error: %@",
tokenResult.error);
}
NSString *appCheckTokenFragment = [@"fac="
stringByAppendingString:tokenResult
.token];
[components
setFragment:appCheckTokenFragment];
if (completion) {
completion([components URL], nil);
}
}];
} else {
if (completion) {
completion([components URL], nil);
}
}
}];
}
Expand Down
52 changes: 37 additions & 15 deletions FirebaseAuth/Sources/Backend/FIRAuthBackend.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@

#import "FirebaseAuth/Sources/Public/FirebaseAuth/FirebaseAuth.h"

#import "FirebaseAppCheck/Interop/FIRAppCheckInterop.h"
#import "FirebaseAppCheck/Interop/FIRAppCheckTokenResultInterop.h"
#import "FirebaseAuth/Sources/Auth/FIRAuthGlobalWorkQueue.h"
#import "FirebaseAuth/Sources/Auth/FIRAuth_Internal.h"
#import "FirebaseAuth/Sources/AuthProvider/OAuth/FIROAuthCredential_Internal.h"
#import "FirebaseAuth/Sources/Backend/RPC/FIRCreateAuthURIRequest.h"
#import "FirebaseAuth/Sources/Backend/RPC/FIRCreateAuthURIResponse.h"
Expand Down Expand Up @@ -615,9 +618,10 @@ + (NSString *)authUserAgent {
GTMFetcherStandardUserAgentString(nil)];
}

+ (NSMutableURLRequest *)requestWithURL:(NSURL *)URL
contentType:(NSString *)contentType
requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration {
+ (void)requestWithURL:(NSURL *)URL
contentType:(NSString *)contentType
requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration
completionHandler:(void (^)(NSMutableURLRequest *_Nullable))completionHandler {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setValue:contentType forHTTPHeaderField:@"Content-Type"];
NSString *additionalFrameworkMarker =
Expand All @@ -641,7 +645,23 @@ + (NSMutableURLRequest *)requestWithURL:(NSURL *)URL
if (languageCode.length) {
[request setValue:languageCode forHTTPHeaderField:kFirebaseLocalHeader];
}
return request;
if (requestConfiguration.appCheck) {
[requestConfiguration.appCheck
getTokenForcingRefresh:false
completion:^(id<FIRAppCheckTokenResultInterop> _Nonnull tokenResult) {
if (tokenResult.error) {
FIRLogWarning(kFIRLoggerAuth, @"I-AUT000018",
@"Error getting App Check token; using placeholder token "
@"instead. Error: %@",
tokenResult.error);
}
[request setValue:tokenResult.token
forHTTPHeaderField:@"X-Firebase-AppCheck"];
completionHandler(request);
}];
} else {
completionHandler(request);
}
}

@end
Expand Down Expand Up @@ -675,17 +695,19 @@ - (void)asyncPostToURLWithRequestConfiguration:(FIRAuthRequestConfiguration *)re
contentType:(NSString *)contentType
completionHandler:
(void (^)(NSData *_Nullable, NSError *_Nullable))handler {
NSMutableURLRequest *request = [FIRAuthBackend requestWithURL:URL
contentType:contentType
requestConfiguration:requestConfiguration];
GTMSessionFetcher *fetcher = [_fetcherService fetcherWithRequest:request];
NSString *emulatorHostAndPort = requestConfiguration.emulatorHostAndPort;
if (emulatorHostAndPort) {
fetcher.allowLocalhostRequest = YES;
fetcher.allowedInsecureSchemes = @[ @"http" ];
}
fetcher.bodyData = body;
[fetcher beginFetchWithCompletionHandler:handler];
[FIRAuthBackend requestWithURL:URL
contentType:contentType
requestConfiguration:requestConfiguration
completionHandler:^(NSMutableURLRequest *request) {
GTMSessionFetcher *fetcher = [self->_fetcherService fetcherWithRequest:request];
NSString *emulatorHostAndPort = requestConfiguration.emulatorHostAndPort;
if (emulatorHostAndPort) {
fetcher.allowLocalhostRequest = YES;
fetcher.allowedInsecureSchemes = @[ @"http" ];
}
fetcher.bodyData = body;
[fetcher beginFetchWithCompletionHandler:handler];
}];
}

@end
Expand Down
29 changes: 13 additions & 16 deletions FirebaseAuth/Sources/Backend/FIRAuthRequestConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#import <Foundation/Foundation.h>

#import "FirebaseAppCheck/Interop/FIRAppCheckInterop.h"
#import "FirebaseAuth/Sources/Backend/FIRAuthRPCRequest.h"
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuth.h"

Expand Down Expand Up @@ -47,6 +48,10 @@ NS_ASSUME_NONNULL_BEGIN
@brief The heartbeat logger used to add heartbeats to the corresponding request's header.
*/
@property(nonatomic, copy, nullable) id<FIRHeartbeatLoggerProtocol> heartbeatLogger;
/** @property appCheck
@brief The appCheck is used to generate a token.
*/
@property(nonatomic, copy, nullable) id<FIRAppCheckInterop> appCheck;

/** @property LanguageCode
@brief The language code used in the request.
Expand All @@ -72,37 +77,29 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (nullable instancetype)initWithAPIKey:(NSString *)APIKey appID:(NSString *)appID;

/** @fn initWithAPIKey:appID:
/** @fn initWithAPIKey:appID:auth:
@brief Convenience initializer.
@param APIKey The API key to be used in the request.
@param appID The Firebase app ID to be passed in the request header.
@param auth The FIRAuth instance used in the request.
@param appID The Firebase app ID to be passed in the request header.
@param auth The FIRAuth instance used in the request.
*/
- (nullable instancetype)initWithAPIKey:(NSString *)APIKey
appID:(NSString *)appID
auth:(nullable FIRAuth *)auth;

/** @fn initWithAPIKey:appID:heartbeatLogger:
/** @fn initWithAPIKey:appID:auth:heartbeatLogger:appCheck:
@brief Designated initializer.
@param APIKey The API key to be used in the request.
@param appID The Firebase app ID to be passed in the request header.
@param heartbeatLogger The heartbeat logger used to add heartbeats to the request header.
*/
- (nullable instancetype)initWithAPIKey:(NSString *)APIKey
appID:(NSString *)appID
heartbeatLogger:(nullable id<FIRHeartbeatLoggerProtocol>)heartbeatLogger;

/** @fn initWithAPIKey:appID:heartbeatLogger:
@brief Designated initializer.
@param APIKey The API key to be used in the request.
@param appID The Firebase app ID to be passed in the request header.
@param auth The FIRAuth instance used in the request.
@param appID The Firebase app ID to be passed in the request header.
@param auth The FIRAuth instance used in the request.
@param heartbeatLogger The heartbeat logger used to add heartbeats to the request header.
@param appCheck The appCheck interop is a library to generate app check token.
*/
- (nullable instancetype)initWithAPIKey:(NSString *)APIKey
appID:(NSString *)appID
auth:(nullable FIRAuth *)auth
heartbeatLogger:(nullable id<FIRHeartbeatLoggerProtocol>)heartbeatLogger
appCheck:(nullable id<FIRAppCheckInterop>)appCheck
NS_DESIGNATED_INITIALIZER;

@end
Expand Down
Loading