Up until recently as of the time of this writing, many native apps are still embedding the OAuth interface in a web view inside the app. This approach has multiple problems, including that the client app can potentially eavesdrop on the user entering their credentials when signing in, or even present a false authorization page. Operating system security has been implemented in a way that the embedded web view doesn’t share cookies with the system’s native browser, so users have a worse experience because they need to enter their credentials each time as well.
The more secure and trusted way to accomplish the authorization flow is by launching a system browser. However, up until recently, this had the drawback of the user beinig popped out of the app and launching their browser, then redirecting back to the app, which is also not an ideal user experience.
Thankfully, the mobile platforms have been addressing the issue. In iOS 9 and 10, developers can now use the
SFSafariViewController API to launch a system browser that shares system cookies from within the app. This is accomplished by the API not allowing the client app to peek inside the browser, getting the security benefits of using an external browser and the user experience benefits of staying within the application the whole time.
Native app developers writing apps for iOS are highly encouraged to use the
SFSafariViewController API, and launch an external Safari window if the API is not available (such as if the app needs to support iOS 8 and below).
Authorization servers should enforce this behavior by attempting to detect whether the authorization URL was launched inside an embedded web view and reject the request if so. The particular techniques for detecting whether the page is being visited in an embedded web view vs the system browser will depend on the platform, but usually involve inspecting the user agent header.