Implement native web auth

This commit is contained in:
Igor Kulikov
2021-06-17 10:29:52 +03:00
parent 8b3a175ead
commit 33562eae89
12 changed files with 236 additions and 13 deletions

View File

@@ -7,7 +7,20 @@ import Flutter
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
self?.registerTbWebAuth()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func registerTbWebAuth() {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: "tb_web_auth", binaryMessenger: controller.binaryMessenger)
let instance = TbWebAuthHandler()
channel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
instance.handle(call: call, result: result)
})
}
}

View File

@@ -0,0 +1,74 @@
import AuthenticationServices
import SafariServices
import Flutter
import UIKit
public class TbWebAuthHandler: NSObject {
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
if call.method == "authenticate" {
let url = URL(string: (call.arguments as! Dictionary<String, AnyObject>)["url"] as! String)!
let callbackURLScheme = (call.arguments as! Dictionary<String, AnyObject>)["callbackUrlScheme"] as! String
var sessionToKeepAlive: Any? = nil // if we do not keep the session alive, it will get closed immediately while showing the dialog
let completionHandler = { (url: URL?, err: Error?) in
sessionToKeepAlive = nil
if let err = err {
if #available(iOS 12, *) {
if case ASWebAuthenticationSessionError.canceledLogin = err {
result(FlutterError(code: "CANCELED", message: "User canceled login", details: nil))
return
}
}
if #available(iOS 11, *) {
if case SFAuthenticationError.canceledLogin = err {
result(FlutterError(code: "CANCELED", message: "User canceled login", details: nil))
return
}
}
result(FlutterError(code: "EUNKNOWN", message: err.localizedDescription, details: nil))
return
}
result(url!.absoluteString)
}
if #available(iOS 12, *) {
let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURLScheme, completionHandler: completionHandler)
if #available(iOS 13, *) {
guard let provider = UIApplication.shared.delegate?.window??.rootViewController as? FlutterViewController else {
result(FlutterError(code: "FAILED", message: "Failed to aquire root FlutterViewController" , details: nil))
return
}
session.presentationContextProvider = provider
}
session.start()
sessionToKeepAlive = session
} else if #available(iOS 11, *) {
let session = SFAuthenticationSession(url: url, callbackURLScheme: callbackURLScheme, completionHandler: completionHandler)
session.start()
sessionToKeepAlive = session
} else {
result(FlutterError(code: "FAILED", message: "This plugin does currently not support iOS lower than iOS 11" , details: nil))
}
} else if (call.method == "cleanUpDanglingCalls") {
// we do not keep track of old callbacks on iOS, so nothing to do here
result(nil)
} else {
result(FlutterMethodNotImplemented)
}
}
}
@available(iOS 13, *)
extension FlutterViewController: ASWebAuthenticationPresentationContextProviding {
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return self.view.window!
}
}