-
Notifications
You must be signed in to change notification settings - Fork 833
Open
Labels
Description
I'm using this in Flutter where I have just the rootViewController. It all works well I can login, the server redirects to the custom scheme of the app.
In my case I redirect the code to the my backend server and from there to the app. After the server responds the app pops up but the callback is not called, nether the application:openURL:options:
What am I missing.
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
static NSString *const kAppAuthExampleAuthStateKey = @"authState";
@implementation AppDelegate {
OIDServiceConfiguration *configuration;
OIDAuthState *authState;
FlutterResult flutterResult;
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
FlutterViewController *controller = (FlutterViewController *) [[self window] rootViewController];
FlutterMethodChannel *channel =
[FlutterMethodChannel methodChannelWithName:@"app_channel" binaryMessenger: controller];
[channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
[self onMethodCall:call result:result];
}];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void) onMethodCall:(FlutterMethodCall *)call result:(FlutterResult )result {
if([@"init" isEqualToString:call.method]){
OIDServiceDiscovery *doc = [[OIDServiceDiscovery alloc] initWithJSON:call.arguments error:nil];
configuration = [[OIDServiceConfiguration alloc] initWithDiscoveryDocument:doc];
} else if([@"authorize" isEqualToString:call.method]) {
if (flutterResult) {
flutterResult = nil;
@throw [NSInvalidArgumentException initWithString:@"Already login in."];
}
flutterResult = result;
NSString *jsonString = call.arguments[@"params"];
NSStringEncoding encoding = 0;
NSData *jsonData = [jsonString dataUsingEncoding:encoding];
NSError *error=nil;
NSDictionary *params = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
NSMutableDictionary *additionalParameters = [[NSMutableDictionary alloc] initWithDictionary: params[@"additionalParameters"]];
if (params[@"display"]) {
[additionalParameters setValue:params[@"display"] forKey:@"display"];
}
if (params[@"prompt"]) {
[additionalParameters setValue:params[@"prompt"] forKey:@"prompt"];
}
NSString *nonce = additionalParameters[@"nonce"];
[additionalParameters removeObjectForKey: @"nonce"];
OIDAuthorizationRequest *request =
[[OIDAuthorizationRequest alloc]
initWithConfiguration: configuration
clientId: params[@"clientId"]
clientSecret:nil
scope: params[@"scope"]
redirectURL: [NSURL URLWithString:params[@"redirectUri"]]
responseType: params[@"responseType"]
state: params[@"state"]
nonce: nonce
codeVerifier: nil
codeChallenge: nil
codeChallengeMethod: nil
additionalParameters: additionalParameters];
_currentAuthorizationFlow = [OIDAuthState
authStateByPresentingAuthorizationRequest:request
presentingViewController:[[self window] rootViewController]
callback:^(OIDAuthState * _Nullable authState, NSError * _Nullable error) {
NSLog(@"%@", [[authState lastAuthorizationResponse] additionalParameters]);
if (authState) {
[self setAuthState:authState];
} else {
result([FlutterError errorWithCode:error.description message:error.description details:nil]);
[self setAuthState:nil];
}
}];
} else {
result(FlutterMethodNotImplemented);
}
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *, id> *)options {
NSLog(@"a| %@", [url absoluteString]);
// Sends the URL to the current authorization flow (if any) which will
// process it if it relates to an authorization response.
if ([_currentAuthorizationFlow resumeExternalUserAgentFlowWithURL:url]) {
_currentAuthorizationFlow = nil;
return YES;
}
NSLog(@"%@", [url absoluteString]);
// Your additional URL handling (if any) goes here.
return NO;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSLog(@"%@", [url absoluteString]);
return [self application:application openURL:url options:@{}];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSLog(@"%@", [url absoluteString]);
return [self application:application openURL:url options:@{}];
}
- (void)didChangeState:(OIDAuthState *)state {
[self saveState];
}
- (void)saveState {
// for production usage consider using the OS Keychain instead
NSData *archivedAuthState = [ NSKeyedArchiver archivedDataWithRootObject:_authState];
[[NSUserDefaults standardUserDefaults] setObject:archivedAuthState
forKey:kAppAuthExampleAuthStateKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)loadState {
// loads OIDAuthState from NSUSerDefaults
NSData *archivedAuthState =
[[NSUserDefaults standardUserDefaults] objectForKey:kAppAuthExampleAuthStateKey];
OIDAuthState *authState = [NSKeyedUnarchiver unarchiveObjectWithData:archivedAuthState];
[self setAuthState:authState];
}
- (void)setAuthState:(nullable OIDAuthState *)authState {
if (_authState == authState) {
return;
}
_authState = authState;
_authState.stateChangeDelegate = self;
[self saveState];
}
@end