Log in to Websites with ASWebAuthenticationSession

Alexey Karimov

If your app integrates with a third-party service that uses OAuth or other web-based login flows, Apple’s ASWebAuthenticationSession is the recommended way to securely handle the authentication process. 

It provides a privacy-conscious, system-managed browser that lets users log in through a web page — and securely return to your app using a custom URL scheme.

What Is ASWebAuthenticationSession?

ASWebAuthenticationSession is part of the AuthenticationServices framework. It allows iOS and macOS apps to open a web-based login page in a secure, sandboxed environment. After the user signs in, the session captures the result via a redirect callback (typically using a custom URL scheme like myapp://auth?token=…).

This API is ideal for:

  • OAuth-based authentication (e.g. Twitter, GitHub, Jira)
  • External login flows in apps that use web services
  • Any login where credentials shouldn’t be collected in-app

How to Use ASWebAuthenticationSession?

Use ASWebAuthenticationSession to log users in through a secure web flow. It opens a browser window, handles authentication, and returns control to your app via a custom URL scheme.

Step 1: Register a Custom URL Scheme

In your Xcode project, go to your app target > Info tab > URL Types. Add a scheme like myapp, which lets the browser redirect back to your app after login.

Step 2: Provide a Presentation Anchor

To present the authentication session properly, your app must implement the ASWebAuthenticationPresentationContextProviding protocol. This tells the system where to present the browser window.

import AuthenticationServices
extension ViewController: ASWebAuthenticationPresentationContextProviding {
    func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
        return self.view.window!
    }
}

Step 3: Create and Configure the Session

ASWebAuthenticationSession uses closures, not async/await. If you need to make async calls inside the callback, wrap them in a Task { } block. Here’s how to create an authentication session and handle the callback:

guard let authURL = URL(string: "https://example.com/auth") else { return }
let callbackScheme = "myapp" // Without '://'

let session = ASWebAuthenticationSession(
    url: authURL,
    callbackURLScheme: callbackScheme
) { callbackURL, error in
    guard error == nil, let callbackURL = callbackURL else {
        // Handle error (e.g., user canceled)
        return
    }

    // Parse the token from the callback URL
    let components = URLComponents(string: callbackURL.absoluteString)
    let token = components?.queryItems?.first(where: { $0.name == "token" })?.value
    print("Token: \(token ?? "No token")")
}

Step 4: Set Context and Configure Privacy

Assign the presentation context provider. Optionally enable ephemeral browsing, which prevents cookies, autofill, and session data from being shared or retained:

session.presentationContextProvider = self
session.prefersEphemeralWebBrowserSession = true

Step 5: Start the Session

Finally, call start() to launch the login flow. This opens a secure browser window. After the user logs in, they’ll be returned to your app with the token or result in the URL.

session.start()
icon If you need to cancel before the user completes authentication: session.cancel()