LinusU / flutter_web_auth

Flutter plugin for authenticating a user with a web service
MIT License
196 stars 169 forks source link

PlatformException(CANCELED, User canceled login, null) on Android #48

Closed jerejacobson closed 1 year ago

jerejacobson commented 3 years ago

Hi, This is my first time using Oauth2 and I am trying to get my callback from the salesforce rest API. I can launch the authenticate() and login to salesforce. Salesforce then re-routes to my call back "myappname://callback?code=aWekysIEeq.....etc", but it throws a PlatformException(CANCELED, User canceled login, null) on android. I check out issue #45 but I am already calling things the right way as far as I can tell. (I might be overlooking the obvious)

I have included the image of the code I am using. (censored both my client_id and redirect_uri "myappname") Capture1

Also, I have my android manifest "intent-filter" inside my main activity. Capture2

If anyone has any ideas or knows of anything I can try I would greatly appreciate it.

thanks!

bl4ckbon3 commented 3 years ago

I'm experiencing the same issue

jerejacobson commented 3 years ago

@bl4ckbon3 I was actually able to fix the issue by importing the project into my own application. (Using the same code as above) It would not work in the GitHub project example that is provided in this repo.(I was using the example one and modifying it just to test the library before writing it into my application.)

Guillaume-Vacelet commented 3 years ago

@jerejacobson I am also experiencing the same issue. My AndroidManifest.xml is setup correctly, and my authenticate method is pretty much the same as yours.

Could you please explain a bit more how you got rid of this issue?

jerejacobson commented 3 years ago

@Guillaume-Vacelet Unfortunately I tried many things so I am not positive which one worked correctly. However, what I did try was to run flutter clean which clears the build cache.

Besides that, I implemented the plugin like the example below. (Not Identical to the project's example)

This is a function to launch the plugin and get the callback scheme and return the result. (The result is parsed for a salesforce keyword in my example )

getAuth() async { //getting the salesforce auth from the user final callbackUrlScheme = 'appname'; try { final result = await FlutterWebAuth.authenticate( url: "https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=*******************&redirect_uri=appname://callback", callbackUrlScheme: callbackUrlScheme); final token = Uri.parse(result).queryParameters['code']; log("\n" + result); log("\n" + token); return token; } on PlatformException catch (e) { log("\n" + e.toString()); return e.toString(); } }

And when I call this function I make sure to use await so my application doesn't continue without the function finishing.

final token = await getAuth();

And finally in my android > app > src > main > AndroidManifest.xml I have the following activity at the bottom right before my </application> closing

'

I hope this info helps you to figure out your issue!

ansells commented 3 years ago

I had this same issue and it turns out the problem was that I had two intent-filter entries with the same scheme. The other one was for my MainActivity. After removing that entry from my Manifest.xml it seems to work now.

kyle-seongwoo-jun commented 3 years ago

same issue here 😢

danielmintz commented 3 years ago

same issue

kyu-suke commented 3 years ago

In my case, it happens when launched other app. e.g. If authenticate URL is twitter.com/xxxxx and twitter app has been installed in Android, twitter app is launched when access the url. And in my case, I will auth tumblr by oauth1.

I resolved this by using SystemChannels.lifecycle in build method as below.

@override
Widget build(BuildContext context) {

  // start
  SystemChannels.lifecycle.setMessageHandler((msg) async {
    if (msg == 'AppLifecycleState.resumed') {
      print('Resumed!');
    }
    return await null;
  });
  // end

  return MaterialApp(/*something widget*/);
}

To be honest, I don't understand why this code in would correct the behavior. I want anyone who know SystemChannels to explain me what this code is doing.

I hope this is helpful to someone else.

pinguluk commented 3 years ago

Had the same issue. You need to add a second activity into your AndroidManifest.xml, instead of putting the intent-filter into your main activity

        ...
        </activity>
        <activity android:name="com.linusu.flutter_web_auth.CallbackActivity">
            <intent-filter android:label="flutter_web_auth">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="YOUR_CALLBACK_URL_SCHEME_HERE" />
            </intent-filter>
        </activity>
    </application>
</manifest>
timshadel commented 3 years ago

I already had the activity setup as both the README and @pinguluk describe, but I was still having this issue.

My problem was that I stupidly tried using a mixed-case URL scheme. When the redirect happened, the provider (rightly) lowercased the scheme, but the CallbackActivity looks for the expected callback as a (case-sensitive, obviously) string key in a map. Since it can't find the callback, nothing happens. Later the cleanup method runs and throws this exception. Making sure I used a fully lowercase callback scheme solved everything.

maysamsh commented 2 years ago

I have the same issue and I tried all the proposed workarounds, I assume in my case it happened after I set the target version of the project to 31. could it be that?

maysamsh commented 2 years ago

in my case I had to set android:exported="true" in:


<activity android:name="com.linusu.flutter_web_auth.CallbackActivity" android:exported="true">
           <intent-filter android:label="flutter_web_auth">
               <action android:name="android.intent.action.VIEW" />
               <category android:name="android.intent.category.DEFAULT" />
               <category android:name="android.intent.category.BROWSABLE" />
               <action android:name="FLUTTER_NOTIFICATION_CLICK" />
               <category android:name="android.intent.category.DEFAULT" />
               <data android:scheme="ananta-dev" />
               <data android:scheme="ananta" />
           </intent-filter>
       </activity>```
FM1337 commented 2 years ago

This is gonna sound dumb but: for the callback schema within the .dart file, don't have a :/ in your variable value, you don't want (at-least in my case) that for when calling the authenticate function with the callbackUrlSchema, because I had a :/ or :// or ://callback in my case, it was causing the thing to fail on Android.

LinusU commented 1 year ago

The callback scheme will be validated in the next version: https://github.com/LinusU/flutter_web_auth/commit/4f89925117e31c9874e60c7bc379967233505284

We've also added a troubleshooting section: https://github.com/LinusU/flutter_web_auth#troubleshooting

LukGaming commented 1 year ago

Does anyone solved it? iam still having problems

lawuysal commented 1 year ago

Yes, same problem continues while accessing to Spotify Web API. I'm authenticating with browser but it's coming null instead of new callback url.

lawuysal commented 1 year ago

I solved it and I'm happier then ever. In my case I forgot the change urlschme after url parameter in the FlutterWebAuth2.authenticate method.

momokazi commented 2 months ago

Yes, same problem continues while accessing to Spotify Web API. I'm authenticating with browser but it's coming null instead of new callback url.

Hey Did you find a fix for that? Im on the same page

lawuysal commented 2 months ago

Yes, same problem continues while accessing to Spotify Web API. I'm authenticating with browser but it's coming null instead of new callback url.

Hey Did you find a fix for that? Im on the same page

It's been more than a year so I can't remember it well. But you can check my repo for creamlight music player which has the answer for this.