expo: WebBrowser.openAuthSessionAsync returns "dismiss" even when the user successfully logged in
š Bug Report
Weāre doing OAuth2 and the user logs in using WebBrowser.openAuthSessionAsync. If the user dismisses the browser without logging in, we catch this by checking result.type == "dismiss".
Unfortunately, we always get 'dismiss', even if the user logged in succesfully. That means our check for whether the browser was dismissed is useless now.
Environment
Expo CLI 3.4.1 environment info: System: OS: Windows 10 Binaries: npm: 6.9.0 - C:\Program Files\nodejs\npm.CMD IDEs: Android Studio: Version 3.5.0.0 AI-191.8026.42.35.5900203
App target is Android.
Steps to Reproduce
-
Attach a listener to handle linking.
Linking.addEventListener('url', this.handleOpenURL); -
Use openAuthSessionAsync to redirect to OAuth2
const redirectUrl = await Linking.makeUrl(...); var result = await WebBrowser.openAuthSessionAsync( uri + '?response_type=code' + '&client_id=' + process.env.OAUTH_CLIENT_ID + '&redirect_uri=' + encodeURIComponent(redirectUrl) + '&state=' + challenge.state + '&code_challenge=' + challenge.code_challenge + '&code_challenge_method=' + challenge.method); -
Right after the await, check the result type for the case where the user canceled the login.
if (result.type == "dismiss") { // Browser was dismissed without logging in. this.setState({ ...this.state, status: 'ERROR', message: "Our error message" }); } -
Open the browser and successfully log in.
Expected Behavior
The user logs in and does not see the error that is associated with 'dismiss'. The message "Our error message" should not be shown.
In essence, in code I expected type == "opened", because the user didnāt cancel.
Actual Behavior
The error message is shown briefly š¦ After a short pause, the listener catches the redirect and processing the succesful login continues as expected.
I created this as a question, not an issue, because I donāt know if there is another way I should be handling the type == "dismiss" instead of right after the await. Any suggestions are most welcome.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 16 (5 by maintainers)
For those that still couldnāt find an answer, my answer was just adding the redirectUrl into the query. On iOS I didnāt need to -
const result = await WebBrowser.openAuthSessionAsync(authUrl)worked fine. But on Android I needed to add the second param -const result = await WebBrowser.openAuthSessionAsync(authUrl, redirectUri)like here - https://docs.expo.io/versions/latest/sdk/webbrowser/#webbrowseropenauthsessionasyncurl-redirecturlFor those struggling to create a redirectUri, you can use
expo-linking.let login = await WebBrowser.openAuthSessionAsync(url, redirectUri)Always returns type: dismiss on Android.
Just ran into this issue on Expo 43 on my Pixel 4 API 30 simulator. The above comment to set
redirectUriseems to have resolved it.SOLUTION!
If your site is deeplinking like: com.fck.you:// the create redirectUri will make com.fck.you:/// just copy ur scheme/ bundle and use com.fck.you:// as redirectUri
this solution was brought to you in the name of JESUS. pray to the Lord and repent for your sins
Iām so confused. Iām just trying to get Google Login working on the Android Standalone app. Iāve been stuck on this for month and donāt even know if Iām on the right thread anymore. š¦
@cruzach the documentation on Handling deep links from the WebBrowser says:
The older Expo example repo also does this here.
So I think that may be where @DianaKoenraadtās last question was coming from.
Based on my testing with Expo SDK 36, if you call
WebBrowser.openAuthSessionAsyncand then cancel the modal web browser on iOS, you get a result.type of ācancelā. If you do the same on Android you get a result.type of ādismissā. The two are inconsistent.I would expect both platforms to never return āopenā (unless you are calling
WebBrowser.openBrowserAsyncinstead ofWebBrowser.openAuthSessionAsync, since they behave differently on Android).Another confusing thing in all this: The documentation for both dismissBrowser and openAuthSessionAsync says they are iOS only. And yet using
WebBrowser.openAuthSessionAsync()on Android not only seems to work, but works much better than trying to roll your own version with vanillaWebBrowser.openBrowser.Perhaps that could also be clarified?