Resuming journeys using magic links on iOS
PingOne Advanced Identity Cloud PingAM iOS
To resume a journey in an iOS app, complete the following tasks:
- Step 1. Capturing the resume URI
-
Configure your iOS application to launch when the user clicks the magic link in their email.
After launching, capture the URI that was clicked so you can resume authentication.
- Step 2. Resuming a suspended authentication journey
-
Pass the captured URI into the
journey.resume()method to continue the journey, rather than callingjourney.start()to start again.
Step 1. Capturing the resume URI
Your application must capture the resume URI that the server emails to the user. That URI contains a unique suspendedId parameter that it uses to resume the user’s journey on the server.
You must register your iOS app to launch when the user clicks the resume URI, so that they can continue their journey in your app. If you don’t register an app to handle the resume URI, clicking a magic link launches your server’s login UI in a browser instead.
|
We recommend using universal links to associate your iOS app with your resume URI. |
Your app should capture the URI value that opened it, as you’ll need to pass that value back to your server to resume the authentication journey.
|
Since universal links could provide a potential attack vector, you must validate any incoming A malicious actor might attempt to craft a URL to compromise your app, so ensure you discard any malformed or unexpected URLs and only use the link to resume an authentication journey. |
Where you capture the URI depends on how you have set up your app. Commonly, you’ll capture the URI in an AppDelegate or SceneDelegate file:
-
AppDelegate
-
SceneDelegate
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
// Get resume URI from the incoming user activity
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL else {
return false
}
}
func scene(_ scene: UIScene, willConnectTo
session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
// Get resume URI from the incoming user activity
guard let userActivity = connectionOptions.userActivities.first,
userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL else {
return
}
}
Step 2. Resuming a suspended authentication journey
After obtaining the resumeUri, use it in your application to continue the user’s authentication or registration journey.
Use the Journey module’s resume() method, rather than start(), to continue the journey using the resumeUri as follows:
let node = await journey.resume(resumeUri)
// Handle nodes just like starting new journey...
switch node {
case let continueNode as ContinueNode:
// Proceed to the next step in the authentication journey
let nextNode = continueNode.next()
case let errorNode as ErrorNode:
// Handle server-side errors (e.g., invalid credentials)
let errorMessage = errorNode.message
let input = errorNode.input // Access the raw JSON response with the input attribute
// Display error to the user
case let failureNode as FailureNode:
// Handle unexpected errors (e.g., network issues, unexpected errors like parsing response)
let errorCause = failureNode.cause
// Log the error and potentially display a generic message
case let successNode as SuccessNode:
// Authentication successful, retrieve the session
let session = successNode.session
let input = successNode.input // Access the raw JSON response with the input attribute
// Proceed with post-authentication actions
default:
break
}
|
If the URI scheme, host, or port in the |