Please describI’m trying to implement Google Sign-In in my Ionic + Capacitor app using AWS Cognito Hosted UI and Amplify v6. The end goal is simple: tap “Login with Google,” open the system browser, authenticate, and have the app receive the redirect so Amplify can finish the PKCE flow and give me tokens.
Setup
-
Ionic + Capacitor (Android + iOS + Web).
-
Cognito User Pool with Google as an IdP.
-
Cognito Hosted UI domain:
login.mydomain.com. -
Separate app clients for web and native.
-
Android Manifest and iOS URL types include an intent filter for
myapp://callback.
Issues Encountered
-
If navigation happens inside the WebView:
Google rejects with403 disallowed_useragent. -
If Hosted UI opens in system browser with
http://localhostas redirect:
Browser shows “localhost refused to connect.” -
If I only configure the custom scheme (myapp://callback):Amplify v6 often throws:
InvalidRedirectException: signInRedirect or signOutRedirect had an invalid format or was not found
before any browser opens. -
Sometimes
redirect_uriis sent as a comma-joined list (all values from the array), which Cognito rejects. -
Even in the best case (browser opens, login works, redirect fires):
The return redirect is not recognized by Amplify once the app is reopened. The?codeandstatenever get processed into a valid session.
Current Code (simplified / genericized)
import { Amplify } from "aws-amplify";
import { Capacitor } from "@capacitor/core";
import { App as CapApp } from "@capacitor/app";
import { signInWithRedirect } from "@aws-amplify/auth";
export function initAmplify() {
const platform = Capacitor.getPlatform();
const isNative = platform === "ios" || platform === "android";
const domain = "login.mydomain.com"; // Cognito Hosted UI domain (no https://)
const webRedirect = `${window.location.origin}/`;
const nativeRedirects = [
"http://localhost/",
"capacitor://localhost/",
"myapp://callback",
];
Amplify.configure({
Auth: {
Cognito: {
userPoolId: "us-east-1_XXXXXXX",
userPoolClientId: isNative
? "NATIVE_CLIENT_ID"
: "WEB_CLIENT_ID",
loginWith: {
oauth: {
domain,
scopes: ["openid", "email", "profile"],
responseType: "code",
redirectSignIn: isNative ? nativeRedirects : [webRedirect],
redirectSignOut: isNative ? nativeRedirects : [webRedirect],
},
},
},
},
});
}
// Button handler
async function login() {
await signInWithRedirect({ provider: "Google" });
}
// Deep-link handler
CapApp.addListener("appUrlOpen", ({ url }) => {
try {
const u = new URL(url);
if (u.protocol === "myapp:" && u.hostname === "callback") {
const code = u.searchParams.get("code");
const state = u.searchParams.get("state");
if (code && state) {
const dest = `${window.location.origin}/authevent/?code=${encodeURIComponent(code)}&state=${encodeURIComponent(state)}`;
window.location.replace(dest);
}
}
} catch {}
});
What I Want
At the end of the day, I just want:
-
Tap “Login with Google.”
-
System browser opens Cognito Hosted UI.
-
After login, app is reopened via redirect.
-
Amplify v6 completes PKCE and
fetchAuthSession()shows valid tokens.
Ask
Has anyone gotten this combination working with Amplify v6 (not v5) and without adding a separate hosted redirect domain?
-
How do you configure Amplify v6 so that the custom scheme redirect is accepted for native without
InvalidRedirectException? -
Is there a known pattern for correctly handing
?code&stateback into Amplify in a Capacitor app? -
Any Ionic/Capacitor gotchas specific to OAuth redirects I might be missing?