Email/SMS Authentication

Register or login a user using One-Time Passcodes or Magic Links in your Swift app

As of this writing, your Passage app will default to One-Time Passcodes, but you can also choose to use Magic Links instead. Both One-Time Passcodes and Magic Links can be sent via email or phone (depending on what kind of identifier your user provides).

Passage highly recommends using One-Time Passcodes over Magic Links, as they are easier to implement, more secure, and a better user experience.

One-Time Passcode (OTP)

Register or log in with OTP

To register or log in a user using a One-Time Passcode, use passage.oneTimePasscode.register or passage.oneTimePasscode.login. Both of these methods will return a OneTimePasscode struct that will contain an id you'll use to finish the authentication process.

do {
    let otpId = try await passage.oneTimePasscode.register(identifier: identifier).otpId
    // Use this otpId for OTP activation.
} catch {
    // Handle error
}

Activate OTP

When the user inputs their OTP into your app, you'll send their input string along with the OTP id through passage.oneTimePasscode.activate.

do {
    try await passage.oneTimePasscode.activate(otp: userInput, id: otpId)
    // Do authenticated stuff
} catch {
    // Handle error
}

Magic Links

Register or log in with Magic Links

To register or log in a user using a Magic Link, use passage.magicLink.register or passage.magicLink.login. Both of these methods will return a MagicLink struct that will contain an id you can use to check the Magic Link status.

do {
    let magicLinkId = try await passage.magicLink.register(identifier: identifier).id
    // Use this magicLinkId to check Magic Link status.
} catch {
    // Handle error
}

Activate Magic Link

If the user opens the Magic Link from the same iOS/macOS/visionOS device and you've set up your app correctly, that link will open your app and you can grab the Magic Link string from your SceneDelegate (see example here). Then you can call passage.magicLink.activate(magicLink) to authenticate the user.

do {
    try await passage.magicLink.activate(magicLink: magicLinkFromRedirectUrl)
    // Do authenticated stuff
} catch {
    // Handle error
}

Check Magic Link status

If the user opens the Magic Link on a different device or you have not setup app links, it is up to your web front end to handle and activate the Magic Link. In this case, you’ll need to continually check the status of the link in your Swift app. Once the Magic Link has been activated by the web front end, passage.magicLink.status(id) will return an AuthResult and your user will be authenticated.

func checkMagicLinkStatus() async {
    guard let token = try? await passage.magicLink.status(id: magicLinkId).authToken else {
        // Magic link not activated yet, check again later.
        return
    }
    // Magic link activated! Do authenticated stuff
}