aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.44k stars 2.13k forks source link

SignInWithRedirect wont work with deeplinks on ionic #13521

Open eholiveira-buspay opened 5 months ago

eholiveira-buspay commented 5 months ago

Before opening, please confirm:

JavaScript Framework

Angular

Amplify APIs

Authentication

Amplify Version

v6

Amplify Categories

auth

Backend

Amplify CLI

Environment information

``` # Put output below this line System: OS: Windows 11 10.0.22631 CPU: (12) x64 AMD Ryzen 5 5600X 6-Core Processor Memory: 2.32 GB / 15.95 GB Binaries: Node: 20.11.1 - C:\Program Files\nodejs\node.EXE npm: 10.2.4 - C:\Program Files\nodejs\npm.CMD Browsers: Edge: Chromium (126.0.2592.61) Internet Explorer: 11.0.22621.3527 npmPackages: @angular-devkit/build-angular: ^18.0.0 => 18.0.3 @angular-eslint/builder: ^18.0.0 => 18.0.1 @angular-eslint/eslint-plugin: ^18.0.0 => 18.0.1 @angular-eslint/eslint-plugin-template: ^18.0.0 => 18.0.1 @angular-eslint/schematics: ^18.0.0 => 18.0.1 @angular-eslint/template-parser: ^18.0.0 => 18.0.1 @angular/animations: ^18.0.0 => 18.0.2 @angular/cli: ^18.0.0 => 18.0.3 @angular/common: ^18.0.0 => 18.0.2 @angular/compiler: ^18.0.0 => 18.0.2 @angular/compiler-cli: ^18.0.0 => 18.0.2 @angular/core: ^18.0.0 => 18.0.2 @angular/forms: ^18.0.0 => 18.0.2 @angular/language-service: ^18.0.0 => 18.0.2 @angular/localize: ^18.0.0 => 18.0.2 @angular/platform-browser: ^18.0.0 => 18.0.2 @angular/platform-browser-dynamic: ^18.0.0 => 18.0.2 @angular/router: ^18.0.0 => 18.0.2 @capacitor/android: 6.0.0 => 6.0.0 @capacitor/app: 6.0.0 => 6.0.0 @capacitor/browser: ^6.0.0 => 6.0.0 @capacitor/cli: 6.0.0 => 6.0.0 @capacitor/core: 6.0.0 => 6.0.0 @capacitor/haptics: 6.0.0 => 6.0.0 @capacitor/ios: 6.0.0 => 6.0.0 @capacitor/keyboard: 6.0.0 => 6.0.0 @capacitor/status-bar: 6.0.0 => 6.0.0 @ionic/angular: ^8.0.0 => 8.2.1 @ionic/angular-toolkit: ^11.0.1 => 11.0.1 @ng-bootstrap/ng-bootstrap: ^16.0.0 => 16.0.0 @popperjs/core: ^2.11.8 => 2.11.8 @types/diacritics: ^1.3.3 => 1.3.3 @types/jasmine: ~5.1.0 => 5.1.4 @typescript-eslint/eslint-plugin: ^6.0.0 => 6.21.0 @typescript-eslint/parser: ^6.0.0 => 6.21.0 aws-amplify: ^6.3.5 => 6.3.5 aws-amplify/adapter-core: undefined () aws-amplify/analytics: undefined () aws-amplify/analytics/kinesis: undefined () aws-amplify/analytics/kinesis-firehose: undefined () aws-amplify/analytics/personalize: undefined () aws-amplify/analytics/pinpoint: undefined () aws-amplify/api: undefined () aws-amplify/api/server: undefined () aws-amplify/auth: undefined () aws-amplify/auth/cognito: undefined () aws-amplify/auth/cognito/server: undefined () aws-amplify/auth/enable-oauth-listener: undefined () aws-amplify/auth/server: undefined () aws-amplify/data: undefined () aws-amplify/data/server: undefined () aws-amplify/datastore: undefined () aws-amplify/in-app-messaging: undefined () aws-amplify/in-app-messaging/pinpoint: undefined () aws-amplify/push-notifications: undefined () aws-amplify/push-notifications/pinpoint: undefined () aws-amplify/storage: undefined () aws-amplify/storage/s3: undefined () aws-amplify/storage/s3/server: undefined () aws-amplify/storage/server: undefined () aws-amplify/utils: undefined () bootstrap: ^5.3.3 => 5.3.3 credit-card-type: ^10.0.0 => 10.0.0 diacritics: ^1.3.0 => 1.3.0 eslint: ^8.57.0 => 8.57.0 eslint-plugin-import: ^2.29.1 => 2.29.1 eslint-plugin-jsdoc: ^48.2.1 => 48.2.8 eslint-plugin-prefer-arrow: 1.2.2 => 1.2.2 ionicons: ^7.0.0 => 7.4.0 ionicons-loader: undefined () ionicons/components: undefined () ionicons/icons: 7.4.0 jasmine-core: ~5.1.0 => 5.1.2 (4.6.1) jasmine-spec-reporter: ~5.0.0 => 5.0.2 karma: ~6.4.0 => 6.4.3 karma-chrome-launcher: ~3.2.0 => 3.2.0 karma-coverage: ~2.2.0 => 2.2.1 karma-coverage-coffee-example: 1.0.0 karma-jasmine: ~5.1.0 => 5.1.0 karma-jasmine-html-reporter: ~2.1.0 => 2.1.0 ng-recaptcha: ^13.2.1 => 13.2.1 ngx-cookie-service: ^18.0.0 => 18.0.0 ngx-mask: ^17.0.8 => 17.0.8 node-example: 1.0.0 protractor-example: 1.0.0 rxjs: ~7.8.0 => 7.8.1 rxjs/ajax: undefined () rxjs/fetch: undefined () rxjs/operators: undefined () rxjs/testing: undefined () rxjs/webSocket: undefined () swiper: ^8.4.5 => 8.4.5 swiper_angular: 0.0.1 tailwind: ^4.0.0 => 4.0.0 tslib: ^2.3.0 => 2.6.3 (2.6.2, 1.14.1) typescript: ~5.4.0 => 5.4.5 typescript-example: 1.0.0 uuid: ^9.0.1 => 9.0.1 (3.3.2, 8.3.2) zone.js: ~0.14.2 => 0.14.6 npmGlobalPackages: corepack: 0.23.0 npm: 10.2.4 ```

Describe the bug

I'm trying to sign in with redirect in an Ionic native application (Android, iOS), but when I call the function, it throws an error in the console, as shown in the images below:

image

image

The problem is, when I start my app in Android, the origin URL in the WebView is localhost as shown in the image below:

image

But the redirect sign-in and sign-out URL in aws-exports is: "appitape://app-itapemirim/callback/"

Looking at your code, I think I found the problem. Now, you check if the current web URL is the same as the redirect URL in aws-exports, but with apps, sometimes it will not be the same.

image

Expected behavior

The expected behavior is that the function signInWithRedirect() works with different origin and redirect URLs.

Reproduction steps

  1. Create an Ionic/Capacitor project with Angular using the latest available versions.

  2. Use the Amplify CLI to configure a new project and add the Auth feature.

  3. Add the Android and iOS projects to your application.

  4. Configure the deep links on Android and iOS as per the Amplify documentation.

  5. Create a login screen that calls the signInWithRedirect method.

  6. Start the Android or iOS project and try to trigger the method.

Code Snippet

// Put your code below this line.

Log output

``` // Put your logs below this line ERROR InvalidRedirectException: signInRedirect or signOutRedirect had an invalid format or was not found. at 7373 (https://localhost/main.5249ca7b4ffdb61a.js:1:478663) at t (https://localhost/runtime.11fc316cf9f715c1.js:1:128) at 287 (https://localhost/main.5249ca7b4ffdb61a.js:1:494254) at t (https://localhost/runtime.11fc316cf9f715c1.js:1:128) at 4743 (https://localhost/main.5249ca7b4ffdb61a.js:1:484030) at t (https://localhost/runtime.11fc316cf9f715c1.js:1:128) at 7696 (https://localhost/main.5249ca7b4ffdb61a.js:1:105043) at t (https://localhost/runtime.11fc316cf9f715c1.js:1:128) at Te (https://localhost/main.5249ca7b4ffdb61a.js:1:649604) at https://localhost/main.5249ca7b4ffdb61a.js:1:649624 ```

aws-exports.js

/ eslint-disable / // WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.

const awsmobile = { "aws_project_region": "us-east-1", "aws_cognito_region": "us-east-1", "aws_user_pools_id": "***", "aws_user_pools_web_client_id": "****", "oauth": { "domain": "contasitapedev.auth.us-east-1.amazoncognito.com", "scope": [ "email", "openid", "profile", "phone", "aws.cognito.signin.user.admin" ], "redirectSignIn": "appitape://app-itapemirim/callback/", "redirectSignOut": "appitape://app-itapemirim/callback/", "responseType": "code" }, "aws_cognito_username_attributes": [], "aws_cognito_social_providers": [ "GOOGLE", "APPLE" ], "aws_cognito_signup_attributes": [], "aws_cognito_mfa_configuration": "OFF", "aws_cognito_mfa_types": [], "aws_cognito_password_protection_settings": { "passwordPolicyMinLength": 6, "passwordPolicyCharacters": [ "REQUIRES_NUMBERS" ] }, "aws_cognito_verification_mechanisms": [ "EMAIL" ] };

export default awsmobile;

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

HuiSF commented 5 months ago

Hi @eholiveira-buspay thanks for opening this issue. For a better understanding do you mean your app is entirely a web app running inside a WebView of the iOS and Android host apps?

Create an Ionic/Capacitor project with Angular using the latest available versions.

eholiveira-buspay commented 5 months ago

@HuiSF Hi, Thanks for the answer!

Yes, that's correct. Ionic is a framework that allows you to develop hybrid applications. This means you create a web application using technologies like HTML, CSS, and JavaScript, and this application runs inside a WebView on Android and iOS devices. The WebView is basically an embedded browser within the native app, allowing the web application to run as if it were a native application. This enables you to develop a single codebase that can be used across multiple platforms.

I already have a Ionic app deployed using aws-amplify v5 working in production on Android and iOS, I'm trying to update my project to v6 and i'm facing this issue.

HuiSF commented 5 months ago

Thanks for the additional information @eholiveira-buspay .

From your description, when the sign in with Google (for example) is initiated, the redirection to the Google sign in page is happening inside the WebView, and the end user is not leaving the native host app. When it redirect back to after signing in Google, it still stays in the WebView to the url https://localhost/home, in this case, I think this url should be your redirectSignIn instead of the app scheme url. Can you confirm?

eholiveira-buspay commented 5 months ago

@HuiSF Hello, thank you again for your attention....

Answering your question: No, actually when I start the federated login process, the application's behavior is as follows:

It opens the user's default mobile browser, such as Chrome or Safari. After completing the login on browser, it uses the app scheme URL to reopen the application and finish the process.

I couldn't make Amplify navigate to the Google or Apple login URL within the webview. If I could, I would be able to easily return it to localhost, which would be much better in this case, even for the user experience.

But unfortunately, I depend on the user's mobile browser to log in to their provider and then reopen the app. That's why I use the app scheme URL as a redirect.

cwomack commented 5 months ago

@eholiveira-buspay, just wanted to link a related feature request #3537 for improved Ionic support with Amplify out of the box. There's a few comments within that issue that detail some ways to potentially get this working with v6, but we have no documented "happy paths" at this point.

I'll bring both this issue as well as other related ones tied to Ionic to our product team to see if we can get further clarity.

eholiveira-buspay commented 5 months ago

@cwomack Thanks for your attention!

Yes, I think it will be good to have a dedicated Ionic integration for AWS Amplify.

For now, I think that removing that section of the code which checks if the origin URL is the same as the redirect URL will be a workaround, just to enable the Ionic native integration with AWS Amplify.

Because as I said before, I already have an app in production using AWS Amplify v5 working well.

For now, I'll try to downgrade Angular's and Ionic's versions to use v5 again until a new version of AWS Amplify is released.

Anyway, thanks again for your attention and for @HuiSF's attention too.

trickstival commented 3 months ago

Why not bring back urlOpener() like in Amplify v5? That would allow ionic users to open the URL using the embedded browser

ebk46 commented 2 months ago

We had/have this problem. Since urlOpener() is gone, we had to monkeypatch the repo to bring back some of that functionality. It's a fairly small monkeypatch and works well, but obviously not a great long-term solution. If you're interested, we updated the openAuthSession() function to use the Capacitor Browser instead of window.location.href = when built for mobile. YMMV.

Patch: https://gist.github.com/ebk46/7f0152568af69e6fc7b886cac77b147f

aavila89 commented 2 months ago

For now, I'll try to downgrade Angular's and Ionic's versions to use v5 again until a new version of AWS Amplify is released.

Can you share the ionic - aws-amplify configuration, I can't get the user information after logging in...thanks!

aavila89 commented 2 months ago

We had/have this problem. Since urlOpener() is gone, we had to monkeypatch the repo to bring back some of that functionality. It's a fairly small monkeypatch and works well, but obviously not a great long-term solution. If you're interested, we updated the openAuthSession() function to use the Capacitor Browser instead of window.location.href = when built for mobile. YMMV.

Patch: https://gist.github.com/ebk46/7f0152568af69e6fc7b886cac77b147f

but what value does redirectSignIn take? thanks!

ebk46 commented 3 weeks ago

We had/have this problem. Since urlOpener() is gone, we had to monkeypatch the repo to bring back some of that functionality. It's a fairly small monkeypatch and works well, but obviously not a great long-term solution. If you're interested, we updated the openAuthSession() function to use the Capacitor Browser instead of window.location.href = when built for mobile. YMMV. Patch: https://gist.github.com/ebk46/7f0152568af69e6fc7b886cac77b147f

but what value does redirectSignIn take? thanks!

Not sure what you mean - that patch doesn't change anything about the overall API signatures. signInWithRedirect takes the same parameters (SignInWithRedirectInput). The patch just changes how the redirect actually happens.