1

TL;DR

I'm trying to understand what is the difference between user tapping "Go" button on software keyboard and tapping "Sign In" button rendered on authentication web page when using SFSafariViewController to authenticate user via Azure or any other OAuth provider.

Description

  • We're using various OAuth providers (Azure, Keycloack to name a few) to authenticate users to our native iOS application.
  • We present to a user, browser instance (SFSafariViewController) with login page
  • This page contains username, password fields and a button to sign in
  • When user is entering the password - he/she can either use Log In button on the page or Go button on the iOS software keyboard
  • In both cases login procedure will be triggered and user will be redirected back to proper URL
  • However, if user taps Go button on the software keyboard, application is not being notified about redirect (universal link logic doesn't work) and redirect URL page is being rendered inside SafariViewController
  • It happens in various OAuth providers and can be reproduced only on iOS (when using Android software keyboard button, universal link behaves fine)

We're handling this situation right now by creating special redirect page, which contains special link to a user to tap. Something like "Tap here if you're not automatically redirected back to the application". But I was wondering if there is better solution to this and what is the difference from the OS/Browser perspective between user tapping software keyboard button and HTML page element.

sha
  • 17,824
  • 5
  • 63
  • 98

3 Answers3

1

This is because Universal Links on iOS cannot be programmatically opened. When you click the "Go" button you're essentially programmatically submitting the input form (You can recreate this yourself by typing in the Universal link into the Safari bar and clicking go, the app will not open). A Universal Link can only be opened when a user intentionally taps on the link itself or a link that redirects to the Universal Link.

clayjones94
  • 2,648
  • 17
  • 26
  • User is typing password into web form field. Redirect happens not by user clicking the button, but by server backend receiving the form, doing authentication procedure and then redirecting web page to a different URL. Do you have any links to documentation or articles explaining this behavior? – sha Nov 29 '17 at 22:12
  • 1
    I have been actively searching for this documentation in Apple but since iOS 10 they track the tap on the **original** link and if that domain performs a redirect to a Universal link domain Safari will still register this as a user tap b/c the original link was tapped. It all depends on the interaction with the first link. I'm saying that if you "programmatically" select that original link (Apple qualifies "Go" button as programmatic) and then redirect to the UL, Apple will NOT register this as a link click. I have only discovered this from my own testing. Apple has no docs on it :( – clayjones94 Nov 29 '17 at 23:05
  • Is there way to customize that 'Go' button behavior? Like dismissing the keyboard instead of "programmatically" submitting the form? – sha Nov 29 '17 at 23:09
  • 1
    So clicking "Go" is essentially clicking "Return" and I know there are ways to disconnect the return button from submitting the form. Try something like [this](https://stackoverflow.com/questions/895171/prevent-users-from-submitting-a-form-by-hitting-enter) and see if you can dismiss the keyboard on enter? Pretty ugly but that's all I can think of off the top of my head. – clayjones94 Nov 29 '17 at 23:20
1

Your workaround seems reasonable.

About activating Universal Links when user navigates from keyboard: this case seems to be similar to situation when user types some URL to browser's address bar and tap GO. If user doing this, than the user intent is to stay in browser, not go to the App. So it is logical to not engage Universal Links.

One more way to make better experience for this case: if user navigated to "special redirect page" on iPhone, try to navigate to customURLScheme URL of your App. At this point you already know that the App is installed on this device. Trying to navigate to customURLScheme URL will bring up iOS system dialog, like "Do you want to open XYZ App?". Still this seems a bit better than "Tap here if you're not automatically redirected back to the application".

Probably you already found out that "special redirect page" should be located on different domain than "Universal Links enabled domain". Navigating inside the same domain will not engage Universal Links. For reference, App Preview page that we have, serves essentially the same purpose as yours "special redirect page".

Oleksiy Ivanov
  • 2,454
  • 15
  • 21
  • Thank you. Unfortunately we cannot use custom URI schemes and need to handle regular HTTPS links via Universal Link approach. And yes, we essentially have two custom domains for special redirect page and some JS login inside to make sure that link user clicks will lead to different domain, so universal link handling will be triggered. Handling redirect URL via universal links for OAuth seems to be very generic problem, I can't believe this has not been solved better. – sha Nov 30 '17 at 03:16
  • There are privacy implications to allow redirects/app-opens without user consent. Think about cookie sharing between Safari and SFSafariViewController. This sharing was killed by Apple in iOS 11 for a good reason. Many shady players care about profit much more than about user privacy. Of course, legit use cases, like OAuth are hurt as well. – Oleksiy Ivanov Nov 30 '17 at 03:23
0

Assuming you have control over the OAuth form, I found the following technique to provide a fairly good experience:

<button type="submit" 
        style="visibility:hidden; height: 0; margin: 0; padding: 0;"
        onclick="document.activeElement.blur(); return false;">
</button>

Add this hidden button ABOVE all other submit buttons on your form. When the Go button is pressed, I've observed that it "clicks" the first submit button on the form. This button catches that click, blurs the current input causing the keyboard to be dismissed, and then cancels the form submission. The user then can tap the visible button(s) on the form to complete the process correctly. No need for two flows.

This also allows for users on desktop using the same OAuth form to press Enter to submit the form or to click the buttons.

Jacob Lauzier
  • 865
  • 6
  • 3