amplify-backend
amplify-backend copied to clipboard
Support for custom domain on Auth resource
Environment information
System:
OS: Windows 10 10.0.19045
CPU: (16) x64 Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz
Memory: 13.03 GB / 31.77 GB
Binaries:
Node: 20.15.1 - C:\Program Files\nodejs\node.EXE
Yarn: undefined - undefined
npm: 10.3.0 - C:\Program Files\nodejs\npm.CMD
pnpm: 9.5.0 - ~\AppData\Roaming\npm\pnpm.CMD
NPM Packages:
@aws-amplify/auth-construct: 1.3.0
@aws-amplify/backend: 1.2.0
@aws-amplify/backend-auth: 1.1.3
@aws-amplify/backend-cli: 1.2.5
@aws-amplify/backend-data: 1.1.3
@aws-amplify/backend-deployer: 1.1.0
@aws-amplify/backend-function: 1.3.4
@aws-amplify/backend-output-schemas: 1.2.0
@aws-amplify/backend-output-storage: 1.1.1
@aws-amplify/backend-secret: 1.1.0
@aws-amplify/backend-storage: 1.1.2
@aws-amplify/cli-core: 1.1.2
@aws-amplify/client-config: 1.3.0
@aws-amplify/deployed-backend-client: 1.4.0
@aws-amplify/form-generator: 1.0.1
@aws-amplify/model-generator: 1.0.5
@aws-amplify/platform-core: 1.0.7
@aws-amplify/plugin-types: 1.2.1
@aws-amplify/sandbox: 1.2.0
@aws-amplify/schema-generator: 1.2.1
aws-amplify: 6.5.4
aws-cdk: 2.155.0
aws-cdk-lib: 2.155.0
typescript: 5.5.4
AWS environment variables:
AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
AWS_SDK_LOAD_CONFIG = 1
AWS_STS_REGIONAL_ENDPOINTS = regional
No CDK environment variables
Describe the bug
I have an Amplify Gen 2 NextJS app configured with an external Google OAuth provider. After purchasing a custom domain for my website externally, I successfully configured the app with the custom domain so that when I go to my custom domain from my browser the website homepage loads successfully.
Now, when I log in using Google OAuth, I am redirected to the OAuth consent screen, but it still shows the redirect URL as <userpool>.auth.<region>.amazoncognito.com. To change this I followed the below steps:
Steps:
Set Up Your Custom Domain in AWS Cognito:
Go to the Cognito Console and select your User Pool.
Under the App Integration section, choose Domain name.
Click Use your own domain and enter your custom domain (e.g., auth.yourdomain.com).
Set Up the DNS Record:
In your DNS management console (e.g., Route 53), create a CNAME record.
Point your custom domain (e.g., auth.yourdomain.com) to the AWS Cognito service domain (e.g., your-userpool-id.auth.region.amazoncognito.com).
Verify Your Domain:
Once the DNS changes propagate, Cognito will verify the domain. This can take up to 24 hours.
Update Your Google OAuth Configuration:
Log in to the Google Cloud Console.
Go to APIs & Services > Credentials.
Edit your OAuth 2.0 Client ID and update the Authorized redirect URIs to use your custom domain.
Still it doesn't change the redirect URL because the auto generated amplify_outputs.json still has the amazon default domain <userpool>.auth.<region>.amazoncognito.com. I even tried redeploying the app, still it doesn't pick up the custom domain I configured in the userpool.
I there a way to configure this in the Amplify Gen 2 NextJS backend auth configuration? Or is this a bug?
Reproduction steps
Steps to reproduce given above.
Hey @amalhub, thank you for reaching out. Adding custom domains isnt quite yet supported on defineAuth. Marking this as feature request.
Additionally, manual changes on the console will not reflect when using CDK to deploy resources.
but you should be able to extend the auth resource on the backend.ts using cdk constructs
import {
Certificate,
CertificateValidation,
} from "aws-cdk-lib/aws-certificatemanager"
import { HostedZone } from "aws-cdk-lib/aws-route53"
// create a stack for domain resources
const stack = backend.createStack("Domain")
// if you're not creating additional DNS records you can just use `fromHostedZoneId()`
const hostedZone = HostedZone.fromHostedZoneAttributes(stack, "HostedZone", {
hostedZoneId: <HOSTED_ZONE_ID>,
zoneName: <HOSTED_ZONE_NAME>,
})
// create certificate
const certificate = new Certificate(stack, "Certificate", {
<DOMAIN_NAME>,
validation: CertificateValidation.fromDns(hostedZone),
})
// add the custom domain which should populate the amplify_outputs.json
backend.auth.resources.userPool.addDomain("CustomDomain", {
customDomain: {
domainName,
certificate,
},
})
}
Hi @ykethan,
Thank you for your response and for suggesting an alternative. I will give it a try and reach out if I encounter any further issues.
It's a bit odd to see that this critical feature is missing in AWS Amplify Gen 2. Unusual that I'm the first to request such a feature, as it is a common requirement when deploying a web application to production with federated auth. It almost feels like I am among the first users to go live with a federated login in AWS Amplify.
Having the same issue.
After extending the auth resource on the backend.ts using cdk constructs as explained by @ykethan, how do you get Google OAuth to use the custom cognito user pool domain instead of the default Cognito domain?
@amalhub have your found a workaround for this?
Hi @TobyMessier, I'm yet to try the suggested alternative solution because I submitted my OAuth consent screen for Google review to enable the App logo (hoping that it would hide the ugly AWS cognito URL) and I'm still waiting until the process is complete to try any alternatives.
However to answer your question; how do you get Google OAuth to use the custom cognito user pool domain instead of the default Cognito domain?, I believe you need to update your custom domain URL as one of the Authorized Redirect URLs in the Google OAuth client web application settings. Let me know if you get this to work.
hey @ykethan, extending the auth resource on the backend.ts using cdk constructs as you recommended works to create a Custom domain, but when using the CDK to deploy resources, it automatically reverts back to the Cognito domain. This means users are still asked if they want to continue to the Cognito domain (very confusing for them) rather than the Custom domain.
Basically, this does not populate the amplify_outputs.json:
backend.auth.resources.userPool.addDomain("CustomDomain", { customDomain: { domainName, certificate, }, })
Any suggested workarounds for this?
It appears to me that one underlying issue is here, where the custom resource that pulls in the domain information incorrectly handles custom domains.
// domain
const oauthDomain = userPool.CustomDomain ?? userPool.Domain ?? '';
const fullDomainPath = `${oauthDomain}.auth.${region}.amazoncognito.com`;
The issue is that a CustomDomain should not be treated as a subdomain under amazoncognito.com. Instead, I believe the above code should be changed to:
const fullDomainPath = userPool.CustomDomain ?? `${userPool.Domain}.auth.${region}.amazoncognito.com`
I have also verified this locally by patching the @aws-amplify/backend-auth package and now see the expected custom domain output in amplify_outputs.json.
Edit: If you do test this on an existing stack, note that the way the lambda custom resource runs it will only update its output if the custom resource is recreated.
I believe this works in the frontend UI, im using it in main.tsx
const fullAmplifyConfig: any = {
...amplifyConfig,
Auth: {
...(amplifyConfig.Auth as any),
Cognito: {
...((amplifyConfig.Auth as any).Cognito || {}),
loginWith: {
...((amplifyConfig.Auth as any).Cognito.loginWith || {}),
oauth: {
...((amplifyConfig.Auth as any).Cognito.loginWith.oauth || {}),
domain: "auth.example.com"
}
}
}
},
but I just ran into some other issues because of it
Hey @amalhub @TobyMessier did you guys find a solution?
With all due respect, this is a rather unpleasant discovery.
I am sorry, but how can such a basic feature (the absence of which will obviously make the users of my app wondering whether it is a fishing website they're entering) not be present in something that positions itself as a 'production-ready' system with 'everything you need to build web and mobile apps'?
I apologize to all the devs here; I respect you all. I understand that the marketing and ads isn't a developer's job, but this honestly seems like I was scammed when decided to switch from Firebase.
Can we get an update on this, please?
I spent hours on this issue today and I’m really disappointed. Hard to believe this isn’t a supported feature. The default domain alone is enough to scare people away.
Anyone find a solution to this? I’ve tried mostly all the suggestions here and cannot get it to work with my React Amplify Gen2 app for Google Login. The default Cognito domain is getting utilized after user clicks login button.
Can we get this feature request prioritized? As @amalhub and @uandere mentioned above, this is a fundamental feature.
The goal of using external id provider (e.g. Google) is to increase customer's trust on my app. If we end up showing a cryptic domain in the Google login screen, that trust will likely go away.
any update or workarounds
Looks like https://github.com/aws-amplify/amplify-backend/pull/3024 made the custom domain work for using existing Cognito resources (reference_auth). But it doesn't apply to Cognito resources directly created as part of the Amplify backend stack.
I submitted https://github.com/aws-amplify/amplify-backend/pull/3056 as a stop-gap solution.
This PR allows Amplify app developer to specify a custom domain prefix in defineAuth. So instead of a cryptic url such as db049484d0476df65368.auth.us-east-1.amazoncognito.com, you can have something like <your-app-name>.auth.us-east-1.amazoncognito.com. You just need to do the following in your defineAuth code,
export const auth = defineAuth({
loginWith: {
...
externalProviders: {
...
domainPrefix: '<your-app-name>',
},
},
It is not as good as a completely custom domain (what this issue is requesting), but I think it is better than the status quo.