Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to get proper response post authentication on auth server #36

Closed
i1990jain opened this issue Jan 7, 2019 · 68 comments
Closed

Unable to get proper response post authentication on auth server #36

i1990jain opened this issue Jan 7, 2019 · 68 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@i1990jain
Copy link

i1990jain commented Jan 7, 2019


async loginButton() {
 const deepLink = getDeepLink("home");
    const uniqueId = DeviceInfo.getUniqueID();
    const url = "https://backend.com/?redirect_uri=${deepLink}";
    console.log(url);
    console.log(uniqueId);
    try {
      await InAppBrowser.isAvailable();
      InAppBrowser.openAuth(url, deepLink, {
        // iOS Properties
        dismissButtonStyle: "cancel",
        preferredBarTintColor: "gray",
        preferredControlTintColor: "white",
        readerMode: false,
        // Android Properties
        showTitle: true,
        toolbarColor: "#E73139",
        secondaryToolbarColor: "black",
        enableUrlBarHiding: true,
        enableDefaultShare: true,
        forceCloseOnRedirection: false,
        // Specify full animation resource identifier(package:anim/name)
        // or only resource name(in case of animation bundled with app).
        animations: {
          startEnter: "slide_in_right",
          startExit: "slide_out_left",
          endEnter: "slide_in_right",
          endExit: "slide_out_left"
        },
        headers: {
          "my-custom-header": "backend"
        }
      }).then(result => {
        console.log(result);
        
      });
    } catch (error) {
      Alert.alert(error.message);
    }
  }

I am using the deep linking auth flow example mentioned in the description of the repo. I was able to successfully open the authentication flow in the browser. I am using a Laravel based server to authenticate the user. Once the user is autheticated the server responds with
return redirect('mobileapp://home?token='.$token);

when this happens the browser closes off but then console.log(result); shows me type:dismiss as a result from the browser, I would also like to know if there is a possibility to handle the URL change in the browser component how we do with for WebView onNavigationStateChange with that way also I will have a possibility to see what is the current state of the browser and act accordingly.

@jdnichollsc
Copy link
Member

@i1990jain please attach more info, what platform are you testing?

@jdnichollsc
Copy link
Member

About the redirection, try using Linking.addEventListener('url', ...)

@i1990jain
Copy link
Author

@i1990jain please attach more info, what platform are you testing?

I am testing both on android and iOS

@i1990jain
Copy link
Author

About the redirection, try using Linking.addEventListener('url', ...)

well this is regarding the app I am talking about the fact that once the user is authenticated on the laravel based website which is open in the inappbrowser in am responding with
return redirect('mobileapp://home?token='.$token);
Is that the right way to communicate the result back to the app or not ?
As of now when I do this the inAppbrowser goes away and I just get type:dismiss in console.log

@jdnichollsc
Copy link
Member

About the redirect, it's different per platform:

  • Android: your_android_scheme://your_android_host/home?token=...
  • iOS: your_CFBundleURLName://home?token=...

Do you have the deep linking configuration already for Android (AndroidManifest.xml) and iOS (Info.plist)?

@i1990jain
Copy link
Author

yes I have configured these and the server responds based on the platform ... but in either of the case I just get type:dismiss as the result in the function

"native-base": "^2.8.1",
    "react": "16.6.1",
    "react-native": "0.57.7",
  "react-navigation": "^3.0.8",
"react-native-inappbrowser-reborn": "^1.3.11",

@jdnichollsc
Copy link
Member

Ohh but what version of iOS? what version of Android? The last version of the plugin is working well in our app

captura de pantalla 2019-01-08 a la s 11 45 42 a m

@i1990jain
Copy link
Author

Android 8.0.0
iOS 12.1.1

@i1990jain
Copy link
Author

i1990jain commented Jan 8, 2019

Cannot you just give a brief explaination about what and in which way the response should be returned from the server ?

@jdnichollsc
Copy link
Member

jdnichollsc commented Jan 8, 2019

we have a redirection from the server to the deep linking of the app and when that url is detected by the plugin, the following response is returned: { type: 'success', url: "appscheme://..." }
{ type: 'dismiss' } is returned only when there's an issue or the browser is closed

@i1990jain
Copy link
Author

I tried a lot of different ways of sending back the redirect from the browser, it always got me
{ type: 'dismiss' } I also tried using different versions of react-navigation, but it was of no difference. Then I moved towards handling the Linking as that was working fine as I was able to see that the app is invoked on redirect and on using this I am now able to catch the redirect with the data I am sending as parameters from the backend.

componentDidMount() {
  Linking.addEventListener('url', this._handleOpenURL);
}
componentWillUnmount() {
  Linking.removeEventListener('url', this._handleOpenURL);
}
_handleOpenURL(event) {
  console.log(event.url);
//here I am able to parse the url and extract the data for further processing
}

@i1990jain
Copy link
Author

we have a redirection from the server to the deep linking of the app and when that url is detected by the plugin, the following response is returned: { type: 'success', url: "appscheme://..." }
{ type: 'dismiss' } is returned only when there's an issue or the browser is closed

I think we get { type: 'dismiss' } as on redirect the browser gets dismissed and the Linking eventListener is invoked. I am not sure about this but that's what it seems to me when I use the inappbrowser to login

@jdnichollsc
Copy link
Member

Very odd because we have the same configuration with Linking here https://github.com/proyecto26/react-native-inappbrowser/blob/master/index.js#L119

@jdnichollsc
Copy link
Member

jdnichollsc commented Jan 9, 2019

Can you debug from the plugin and please let me know?

@i1990jain
Copy link
Author

i1990jain commented Jan 11, 2019

Ok so I tried using the same with iOS and it works perfectly but still I haven't been able to get it working for android
tell me if I am going wrong anywhere with the app manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mobileapp">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-feature android:name="android.hardware.camera" android:required="false" />
    <uses-feature android:name="android.hardware.camera.front" android:required="false" />

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:launchMode="singleTask"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="mobileapp" android:host="mobile-host"/>            
    </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>

Also for the confguration of the android app I have MainApplication.java and MainActivity.java

package com.mobileapp;

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;


public class MainActivity extends ReactActivity {

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "mobileapp";
    }

    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
      return new ReactActivityDelegate(this, getMainComponentName()) {
        @Override
        protected ReactRootView createRootView() {
         return new RNGestureHandlerEnabledRootView(MainActivity.this);
        }
      };
    }
}
package com.mobileapp;

import android.app.Application;

import com.facebook.react.ReactApplication;
import com.learnium.RNDeviceInfo.RNDeviceInfo;
import com.proyecto26.inappbrowser.RNInAppBrowserPackage;
import io.github.elyx0.reactnativedocumentpicker.DocumentPickerPackage;
import com.reactnative.ivpusic.imagepicker.PickerPackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

import java.util.Arrays;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
            new RNDeviceInfo(),
            new RNInAppBrowserPackage(),
            new DocumentPickerPackage(),
            new PickerPackage(),
            new VectorIconsPackage(),
            new RNGestureHandlerPackage()
      );
    }

    @Override
    protected String getJSMainModuleName() {
      return "index";
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
  }
}

and my utilities.js

import { Platform } from "react-native";
export const getDeepLink = (path = "") => {
  const scheme = "mobileapp";
  const prefix =
    Platform.OS == "android" ? `${scheme}://mobile-host/` : `${scheme}://`;
  return prefix + path;
};

would like to repeat that it is working fine in iOS ... but in android I am unable to get a proper response and have to use the Linking eventListener to get the incoming url

@jdnichollsc
Copy link
Member

What's the redirection used from the server in the case of Android?

@i1990jain
Copy link
Author

I am redirecting to "mobileapp://mobile-host/home?data="

@jdnichollsc
Copy link
Member

mmm very odd, we have this Android intent:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="app-scheme" android:host="app-host" android:pathPrefix="" />
</intent-filter>

@i1990jain
Copy link
Author

mmm very odd, we have this Android intent:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="app-scheme" android:host="app-host" android:pathPrefix="" />
</intent-filter>

even after adding android:pathPrefix="" it still gets me {type : dismiss}

@jdnichollsc
Copy link
Member

can you debug and put a breakpoint here? https://github.com/proyecto26/react-native-inappbrowser/blob/master/index.js#L114

@jdnichollsc jdnichollsc added the help wanted Extra attention is needed label Feb 18, 2019
@sdsd08013
Copy link

same issue, I encountered.

@jdnichollsc
Copy link
Member

@sdsd08013 please debug and let me know 🙏

@jdnichollsc
Copy link
Member

Any help is really appreciated!

@jdnichollsc
Copy link
Member

Ohhh you can't use android:launchMode="singleTask"

@viewpnt1
Copy link

Encountered the same issue without android:launchMode="singleTask". Anyone found a solution for this yet?

@viewpnt1
Copy link

viewpnt1 commented Jul 31, 2019

@jdnichollsc can you tell me what info you need from debugging, and is it native debug or js debug? I tried almost everything the result is always "dismiss". Also, I noticed that android:launchMode="singleTask"is present in the example app, but same thing happens with or without it.
EDIT: only tested it on android.

@jdnichollsc jdnichollsc reopened this Jul 31, 2019
@jdnichollsc
Copy link
Member

@viewpnt1 let me know the url to debug your authentication because in my case it's working as expected, we're using okta to authenticate the users and the deep linking redirection works very well :)

@jdnichollsc
Copy link
Member

jdnichollsc commented Aug 20, 2019

Is this OK to do?

What happens if the browser is closed but the redirection never responds? Because we have a conditional here to detect deep linking redirection: if (event.url.startsWith(returnUrl))
In this scenario I would prefer adding a timeout by chaining the promise of the open method as I said before.

sometimes I'm gettting the error because the redirectHandler isn't null.

Can you share your code? You can only call _openAuthSessionPolyfillAsync once at a time.

@Luke-Rogerson
Copy link

@jdnichollsc Could you have a look at my PR? Tell me what you think about my fixes! 🙂

@moak
Copy link

moak commented Aug 23, 2019

Same issue here .. :( Working fine on IOS but getting { type: dismiss } on android.

@andresubri
Copy link

I got tired of trying to find a solution, a workaround is to do.

    return await InAppBrowser.openAuth(
      authorizationEndpoint,
      redirectUrl,
      {
        // iOS Properties
        dismissButtonStyle: 'cancel',
        // Android Properties
        showTitle: false,
        enableUrlBarHiding: true,
        enableDefaultShare: false,
      },
    ).then(response => {
      if (response.type === 'success' && response.url) {
        return handleURL(response.url);
      }
      // Android bug: response.type is always dismiss, a workaround is to get the url directly with RN's API
      return Linking.getInitialURL().then(url => {
        if (url) {
          return handleURL(url);
        }
      });
    });

@jdnichollsc
Copy link
Member

Ok guys, debug develop branch and let me know if this PR works for you https://github.com/proyecto26/react-native-inappbrowser/pull/103/files

@jdnichollsc
Copy link
Member

Check the last version 3.1.0 and let me know 👍

@andresubri
Copy link

Just tested
Added waitForRedirectDelay: 10000,
The delay works but still dismiss is coming up

@giacomocerquone
Copy link

Damn... I also ran this example configured by you https://github.com/proyecto26/react-native-inappbrowser/blob/master/example/App.js#L104 and I've got the same problem.
Actually when the redirects is done, the app shuts down and it won't open again and only when I manually open the app back I've got an alert with "type dismissed".

This is really blocking sadly :(

@viewpnt1
Copy link

viewpnt1 commented Sep 9, 2019

@giacomocerquone do you have more than 1 redirect in your login flow?

@giacomocerquone
Copy link

giacomocerquone commented Sep 9, 2019

@viewpnt1 as I said, I'm using the example https://github.com/proyecto26/react-native-inappbrowser/blob/master/example/App.js#L104 and as you can see there is 1 redirect in that login flow.

Plus I tried the deep link externally (just using Linking.openURL) and it is working. So can't understand why it's crashing...

@giacomocerquone
Copy link

giacomocerquone commented Sep 9, 2019

@jdnichollsc very good news guys!
I even managed to remove the error that brought @i1990jain to open this thread (I also think I solved the crash that I was experiencing too)

I previously updated my last comment saying that probably the problem relied in the Android API's I was using, but actually I was wrong.

The broken thing, at least for me, was this page here put up by the owner of this lib: https://github.com/proyecto26/react-native-inappbrowser/blob/gh-pages/index.html

Basically the way he links back to the app is faulty and it can crash your app and result in a "dismissed" action for the lib (at least restructuring that in another way, didn't let my app crash or report a dismissed inappbrowser).
So I basically tried to switch to this page I put up (I put it on gh pages but it still gives back a 404): http://www.webdevout.net/test?04y&raw
and everything worked out nice and perfect for me.

Now, what this probably means?
While triaging this issue I've encountered some blog posts where there was written that in order to test deep linking you can't just open chrome and insert your custom link in the url bar for several reasons. (https://medium.com/react-native-training/deep-linking-your-react-native-app-d87c39a1ad5e)
In fact, one advised way, is to use an "a" tag. Now I'm about to test it out with a meta tag and see what happens in order to make it automatic

UPDATE: not working with

<meta http-equiv = "refresh" content = "2; url = my-demo://demo/home" />

damn... same crash and same "dismissed" alert when I open it back
And it has nothing to do with the "waitforredirectdelay" option, you can raise it up, it won't work

UPDATE2:
to me it seems like there is no solution other than using an a tag and let the user tap it.
For some more info you can see here: https://paul.kinlan.me/deep-app-linking-on-android-and-chrome/

If you find a way, let us know :)

@jdnichollsc
Copy link
Member

I also ran this example configured by you https://github.com/proyecto26/react-native-inappbrowser/blob/master/example/App.js#L104

It looks like JS redirections doesn't work in the case of Android, only works with redirections from backend (HTTP 302), check for more details => https://stackoverflow.com/a/41882732/1532821

@jdnichollsc jdnichollsc added the bug Something isn't working label Sep 9, 2019
@giacomocerquone
Copy link

giacomocerquone commented Sep 10, 2019

@jdnichollsc yes, in fact attaching the deep link url directly to auth0 (they obviously use a 302) it works gracefully
I'm about to prepare a pr for your example in order to put a link there instead of an automatic return to the app
And I'd also add this to the readme

UPDATE: I saw you already updated the example :)
Anyway sometimes my app keeps crashing... I just can't understand when, and why... so sad

@jdnichollsc
Copy link
Member

Anyway sometimes my app keeps crashing...

Can you debug from Android Studio?

Maybe using a redirection from backend is much better from the example

@zealgit
Copy link

zealgit commented Nov 11, 2019

I am still facing same issue of "type:dismiss", has this issue already been fixed?

Can anyone help me with it please?

@jdnichollsc
Copy link
Member

@andresubri thanks for your help, it was fixed in the last version 3.3.0, let me know 👍 https://github.com/proyecto26/react-native-inappbrowser/releases/tag/v3.3.0

@zealgit
Copy link

zealgit commented Nov 12, 2019

@jdnichollsc I've just updated to version 3.3.0 and the issue of "type:dismiss" persists in Android.

Can you please help me with this?

@jdnichollsc
Copy link
Member

Please share more details of your error because I don't know what version of Android you're using, the backend redirection logic you have, the deep linking configuration you did in your project, etc 😅
PD: If this issue is urgent for you, you can contact Tidelift support too 🙂

@zealgit
Copy link

zealgit commented Nov 12, 2019

I've followed same process for deep linking configuration suggested in the example, and redirecting to "appname://callback" url using laravel Redirect::to() function.

I am using Android 7.0 version device.

Android Manifest
image_2019_11_12T07_51_38_869Z

Laravel Redirection:
image_2019_11_12T07_53_44_639Z

React Native Code
image_2019_11_12T07_58_01_728Z

@giacomocerquone
Copy link

giacomocerquone commented Nov 12, 2019

Honestly @jdnichollsc I believe there is a huge misunderstanding with this library due to the example in the readme. I discovered this randomly after having spent a whole day to implement deep linking and the oatuh2 auth flow with an external provider.

I ported an entire expo app to a bare react native app and I used this module to replace the "authsession" module.
On expo I wasn't used to deep link back to the app after a successful authentication, instead I just awaited the value of the promise returned by the open method and I checked that we can do the same with this lib too.
The only thing that prevented us to do so, was this issue because the returned data sometimes were of type dismissed even when the authentication flow went fine and the redirect from the opened webpage went fine and for that reason we were better off using the deep linking flow and handling things manually like @i1990jain showed initially in this issue.

Do you confirm this or I'm wrong about something?

The only other reason I can come up with is that deeplinking must be configured in order to have that response from the promise... is that it?

@jdnichollsc
Copy link
Member

jdnichollsc commented Nov 12, 2019

I don't understand you because we have the same logic from Expo, you need to configure deep linking in your app to be able to redirect the users from browser to the app again and we fixed the race condition issue with the promise when the browser is opened from Android, so check again and let me know, you can debug the JS code of this library from your project (node_modules) using React Native Debugger tool and let us know if the new validation using Linking is not working as expected 🙂 https://github.com/expo/expo/blob/master/packages/expo-web-browser/src/WebBrowser.ts#L179

@jdnichollsc
Copy link
Member

@zealgit please check the example folder of this project and let me know if you can reproduce this issue 👍

@giacomocerquone
Copy link

Sorry for the delay! Not appreciating the downvote, but still...

This is one thing:

InAppBrowser.openAuth(url, deepLink).then((response) => {
          if (response.type === 'success' &&
            response.url) {
            Linking.openURL(response.url)
          }
        })

and this is another:

InAppBrowser.openAuth(url, deepLink).then((response) => {
          if (response.type === 'success' &&
            response.url) {
              followingAuth(response.url)
          }
        })

My question was: deep linking configuration is needed for both ways or just for the first one?

@jdnichollsc
Copy link
Member

jdnichollsc commented Nov 14, 2019

after having spent a whole day

The downvote is about this, we spent more days creating this library, so you can create any pull request if you see an opportunity for improvement in this plugin 👍

About openAuth, deep linking configured properly is required to use that method, otherwise we can't detect the redirection and you need to use Linking directly :)
For more details about deep linking configuration you can see the example project of this repo:

@proyecto26 proyecto26 locked as resolved and limited conversation to collaborators Nov 14, 2019
@jdnichollsc
Copy link
Member

Guys, FYI https://github.com/proyecto26/react-native-inappbrowser/releases/tag/v3.3.2
PD: AppState is required from Android to be able to get the last url when the OnResume event of the Android Activity is called after the redirection, if you see any other error please report in another issue 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

9 participants