Search code examples
iosswiftservervapor

Google Auth with callback on server-side, that I would like to respond to in client-side


I am building an app with a Vapor backend, and Imperial for OAuth. I am trying to implement Google and Facebook sign-in.

When I hit this endpoint: localhost:8080/google , the server authenticates the user, and after that, a callback executes and I receive a token and redirect to a certain path. (callback executing on server-side)

On the client side, I embed this endpoint in a WKWebview, which works fine, but the problem is, that the auth callback is happening on the server side, and not on the client side, which creates an issue, that I cannot execute client-side operations(receiving the token and doing something with it, closing webview and showing an activity indicator and so on..) after the user signed in the embedded web view.

Is there a way to make a client request somehow, to happen only inside the server-side callback after the auth completes? Or should I approach it differently? maybe some server-push to the client, without the client requesting it?

Backend code for the auth:

 try group.oAuth(
        from: Google.self,
        authenticate: "google",
        authenticateCallback: nil,
        callback: "http://localhost:8080/google-complete",
        scope: ["profile", "email"],
        completion: processGoogleLogin
    )

processGoogleLogin:

 func processGoogleLogin(request: Request, token: String) throws -> EventLoopFuture<ResponseEncodable> {
    print("Google Token: ",token)
    return request.eventLoop.future(request.redirect(to: "/"))
    //here theoretically I want to do certain operations on the client side.
}

Client-side code for embedding the webview and hitting the desired endpoint:

 @objc private func googleLogin() {
    let newVC = UIViewController()

    let webConfiguration = WKWebViewConfiguration()
    let webView = WKWebView(frame: newVC.view.frame, configuration: webConfiguration)
    let userAgentValue = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4"
    webView.customUserAgent = userAgentValue
    
    let myURL = URL(string:"http://localhost:8080/google")
    let myRequest = URLRequest(url: myURL!)

    webView.uiDelegate = self
    newVC.view = webView
    webView.load(myRequest)
    self.present(newVC, animated: true)
}

Solution

  • You absolutely should not be using WKWebView for authenticating users with your server, especially over OAuth. Use ASWebAuthenticationSession. Then in your Vapor app in processGoogleLogin redirect to a scheme your iOS app knows about and pass the token as a URL query parameter. Then in the callback you can do whatever you need to on the client side.