expo: Auth session sometimes ends with "Something went wrong trying to finish signing in."

Maintainer edit

The auth session proxy service is deprecated and not recommended for production. For production apps, your app should navigate to the third-party authentication provider directly instead of using this service. This is the official workaround to this issue, which is likely unresolvable due to how browser cookie policies have changed. Follow this migration guide if you are currently using the proxy service.

The migration guide shows how to configure the authentication provider to redirect directly to your app, typically with a deep link with your app’s own URL scheme. In your app, set the useProxy option to false (the default) when calling the promptAsync method, which configures your app not to use this service.

Due to web browser changes like WebKit’s Tracking Prevention, the AuthSession proxy service may not work reliably in edge cases such as when a user’s device is configured to block cookies or prevent cross-site tracking. The AuthSession proxy service does not track nor collect any user data but it requires cookies to correctly redirect back to your app after the user has authenticated with the third-party authentication provider. This service will not work if the browser’s settings or heuristics block cookies.


🐛 Bug Report

Summary of Issue (just a few sentences)

Sometimes when I try logging in using AuthSession it doesn’t redirect me back to app, but shows “Something went wrong trying to finish signing in.” instead. After that when I try again, it works as it should. After numerous tests we assume that this only happens on iOS, it never got reproduced on Android.

I am using expo since version 33, and this never happened before.

Environment - output of expo diagnostics & the platform(s) you’re targeting

  Expo CLI 3.21.9 environment info:
    System:
      OS: macOS Mojave 10.14.4
      Shell: 5.3 - /bin/zsh
    Binaries:
      Node: 10.16.1 - /usr/local/bin/node
      Yarn: 1.15.2 - /usr/local/bin/yarn
      npm: 6.9.0 - /usr/local/bin/npm
    IDEs:
      Xcode: 10.2.1/10E1001 - /usr/bin/xcodebuild
    npmPackages:
      expo: ^37.0.0 => 37.0.11
      react: 16.9.0 => 16.9.0
      react-dom: 16.9.0 => 16.9.0
      react-native: https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz => 0.61.4
    npmGlobalPackages:
      expo-cli: 3.21.9
  Target env: Android & iOS

Reproducible Demo

All I’m doing is:

const {
  data: { redirect_url: redirectUrl }
} = yield ApiClient.get(`app.auth.${socialLoginSite}`); // fetch redirect url from backend, for google or facebook

const result = yield AuthSession.startAsync({
  authUrl: redirectUrl
}); // Everything happens in this call

Steps to Reproduce

Try logging in using facebook or google, for some reason sometimes the final redirect doesn’t work.

Expected Behavior vs Actual Behavior

Expected Behavior: If there is an error, then AuthSession should return with

{
  result: {
    type: "error"
    ...
  }
}

Actual Behavior: AuthSession gets blocked on last step and both users and developers are confused.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 10
  • Comments: 72 (31 by maintainers)

Most upvoted comments

For future reference, I hit this error today when I misused the proxy.

const redirectUri = AuthSession.makeRedirectUri({
    useProxy: false,
});

// ...

promptAsync({ useProxy: false })

This caused the auth to open up to the provider (e.g. facebook.com) but redirect to the proxy auth.expo.io when it was complete. The error was the result of the auth proxy not being able to complete the result because I forgot to start it.

I can confirm that we managed to overcome this by not using the proxy in the production or better said when not using the expo client. We confirmed that the no-proxy solution works with the clients where we were able to reproduce the problem. We kept the proxy for expo client as it’s easier to handle dev and integration stages like this, but you can also fully move to no-proxy solution.

In addition, we had to move away from AuthSession.startAsync to AuthSession.loadAsync and AuthRequest.promptAsync. The reason is that we needed to supply correct information about proxy usage to both makeRedirectUri and promptAsync

Basically this worked for us:

export const isAuthSessionUseProxy = () => Constants.appOwnership === AppOwnership.Expo;

export const getAuthSessionRedirectUrl = () => AuthSession.makeRedirectUri({ native: 'com.myapp://my-redirect-path', useProxy: isAuthSessionUseProxy() });

export const fetchToken = () => {
  // maybe complete auth session first
  WebBrowser.maybeCompleteAuthSession();
  
  // resolve redirect url
  const redirectUrl = getAuthSessionRedirectUrl();
  
  const discovery = {
      authorizationEndpoint: `${Env.AUTH_HOST}/oauth/authorize`,
      tokenEndpoint: `${Env.AUTH_HOST}/oauth/token`
  };
  
  return AuthSession.loadAsync(
      {
          clientId:..,
          redirectUri: redirectUrl,
          extraParams: {
              // anything else you want to pass to authorize endpoint as request param 
          }
      },
      discovery
  )
  .then(request => request.promptAsync(discovery, { useProxy: isAuthSessionUseProxy() }))
  .then(result => { 
     // get the token with the code if the result is successful 
     // don't forget to use the same redirectUrl
   });
}

We are seeing this issue in the production on iOS with Safari’s Prevent Cross-Site Tracking. What’s really anoying is that this has been happening a while and some amount of users where really pissed, as they can not login in the app. Now we discovered this is related exactly to this issue.

@ide I think this is way more critical than “if this is important enough to anyone”… You basically have no idea what browsers will be used to open the login screen and what the settings are. This means that the login can consistently fail for good amount of people. How is this not a big issue?

It’s also a problem that there is no actual workaround for this. If you continue using the AuthSession with proxy: true you will hit this problem and there’s no way out. Or am I missing something?

We currently don’t have a known fix for this due to how Apple has changed Safari’s behavior over the years in response to internet ads and changes in the data tracking landscape. Google may have changed Android/Chrome as well. The little AuthSession server that Expo runs performs no tracking and has no ads obviously but may have been a casualty in Apple & Google’s changes to the web.

Wow. A year later and it’s unfixed. Wasted 3 days of my time. It works fine on ios, but on android AuthSession is still broken.

I’ll try switching to expo-google-app-auth and see how that goes.

i get that problem too, “Something went wrong trying to finish signing in. Please close this screen to go back the app”

We’re also facing this in current development while upgrading to v45. Not really sure why the working expo-google-app-auth was deprecated in favor of a library that doesn’t work all the time for iOS and Android?

https://github.com/expo/expo/blob/sdk-44/docs/pages/versions/v44.0.0/sdk/google.md

We’re attempting some of the fixes above but longer support of expo-google-app-auth would also help.

Hi, all

We’ve been suffering from this problem for a while now. We are using auth0 as our oauth service provider.   We found that the first login always fails if the user’s network connection is under certain conditions. The guess is that it is a network connection problem between the expo auth proxy server and the auth0 auth server. At last, our solution is: skipping the expo auth server and callback to the our app directly.
Now, the error never happens again and everything works fine.

Here is the code:

function login() {
  const redirectUrl = 'app_schema://callback/url/';
  let urlParams = {
    client_id: auth0ClientId,
    response_type: 'token',
    scope: 'openid profile email',
    redirect_uri: redirectUrl,
  };
  let loginParams = {
    authUrl: `${auth0Domain}/authorize` + toQueryString(urlParams),
    returnUrl: redirectUrl
  }
  return AuthSession.startAsync(loginParams);
}

it’s not, but as a summary for how it works:

  • you visit the start auth session page, we save the return url in cookies and send you to the auth page
  • when you are redirected to the finish auth session page, get the return url from cookies, then extract the auth params from the url and append them to the return url and redirect

Have someone found a workaround for users to login again? I currently have some users that see this message every time they try to login and that is quite critical

This package in unstable I waisted whole day and at last downgraded expo to 44 and installed expo-google-app-auth which only took 20 mins to fix this issue.

Hi guys, if anyone is facing this issue on android, do check that you do not have any adblockers/AdGuard enabled. It recently started blocking the returnURI and prevents the final redirect back to the app.

@jakeyr trick to disable “Prevent Cross-Site Tracking” option also allowed our users to log in back

Update: I discovered that at least one user was having this issue due to having “Prevent Cross-Site Tracking” enabled under Settings -> Safari in the Privacy section. I am guessing this has to do with the way you are storing the redirect cookie being blocked somehow, or perhaps the JS on the redirect page not executing correctly while doing some cross-origin requests, etc.

Any chance you can take a look and see if there’s a way to make this work now that you have something to go on?

interesting! that’ll be helpful for reproducing. thanks @rrufus!

@rrufus - happy to reopen if you create a mcve and share it. you can just create a new auth0 account specifically for this purpose so that we are sure we have the exact same setup