OAuth on iOS using the Swift SDK

This guide is for an app developer who needs to integrate with Zephr’s OAuth social sign-in.

Prerequisites

Configure the OAuth client ID and secret for the providers you are using, details on how to can be found on the OAuth 2.0 page.

Add the iOS redirect URI to your Zephr Site (UI for this pending).

This should be either:

Add the Zephr OAuth callback address to your OAuth providers allowed redirects list.
GET https://mysite.com/zephr/oauth/<provider>/ios/callback

The Zephr Swift SDK can be used to make integration with the Zephr Public API simpler in your app. The SDK can be found on BitBucket here.

Implementation

Start the OAuth flow by retrieving the authentication URL for your chosen provider.

A list of providers and how to configure them can be found on the OAuth with the Public API page.

Example startOAuthFlow call:

Copy
Copied
BlaizePublic.client.startOAuthFlow(provider: AuthProvider) { result in
    switch result {
    case .success(let locationUrl):
        // Trigger OAuth flow
    case .failure:
        // Handle failure
    }
}

Using the location URL returned by startOAuthFlow, start an ASWebAuthenticationSession.

Details can be found at ASWebAuthenticationSession.

This will cause the app to launch a webview with the providers OAuth page for the user to authenticate and will return a callbackURL when the configured callbackURLScheme is found.

There are 3 possible outcomes from the OAuth flow callback:

  • Login successful
  • Partial Registration
  • Failure

Login Successful

If the user either already exists in the Zephr User store or if there are no required registration fields, a user will be successfully logged in and a Zephr session ID will be returned.

Example response:
<redirecturi>?action=login&status=success&tracking_id=1234&session_id=1234

Partial Registration

If the user accepts the authentication request but Zephr does not have all the information to create the account in the Zephr User store, a partial registration will return a state key that can be used to fully register a user with the missing registration fields.

Example response:
<redirecturi>?action=register&status=partial&state_key=1234&identifier=user@example.com

Using the state_key returned by the callback, the required fields can be sent to fully register a user.

Copy
Copied
BlaizePublic.client.register(token: token, attributes: \[...\]) { result in
    switch result {
    case .success(let sessionId):
        print("Registration successful")
        // Save the sessionId
    case .userAlreadyExists:
        print("Error: user already exists")
    case .emailDomainBlacklisted:
        print("Error: email domain blacklisted")
    case .badRequest:
        print("Error: bad registration request")
    }
}

Failure

The user denied the authentication request or something went wrong.

Example response:
<redirecturi>?action=login&status=failure&message=...

An example of how to handle the Zephr OAuth callback responses in Swift follows:

Copy
Copied
switch callbackURL?.queryItems\["status"\] {
case "success":
    print("Login successful")
    setUserSessionId(sessionId: queryItems\["session\_id"\])
case "partial":
    print("Partial registration successful")
    triggerPartialRegistration(token: queryItems\["state\_key"\])
case "failure":
    print("Auth response error")
    print(queryItems\["message"\] ?? "")
default:
    print("Unknown auth response status")
    print (callbackURL!)
}

An example login Swift project is available here for reference.