This was done using the amplify cli v0.2.2-multienv.1.
The goal was to:
- Create an auth setup for my React AWS Amplify project
- Use email as the sign up/sign in id and make sure it's unique
- Offer social sign in with Facebook and Google (and have those users also end up in the Cognito user pool—this appeared to only be possible using the hosted UI)
- From the terminal:
amplify add auth
- No, I will set up my own configuration
- User Sign-Up, Sign-In, connected with AWS IAM controls...
- friendly name: - NOTE: this will be the identifier in your AWS console for this Cognito setup, I like to namespace everything in my Amplify projects with the same prefix for my project, so they’re easier to identify
- identity pool: _identitypool
- Allow unauthenticated logins: Yes
- 3rd party: Yes
- Facebook & Google
- See step 2 & 3 of "Cognito - hosted UI setup"
- User pool: _userpool
- Multifactor: OFF
- Email based user reg: Enabled
- Verify subject: [default]
- Verify message: [default]
- Override password policy: Y
- [default:8]
- password requirements: default or whatever you want
- required attrs (none)
- refresh token: [default:30 days] or longer, depending on what you want
- read and write attrs: name, given name
- NOW DO "Cognito - unique email" step
Before running amplify push
go to amplify/backend/auth/<authname>/<authname>-cloudformation-template.yml
and under UserPool:
> Properties:
, if it doesn’t exist yet, add:
# HACK - add these to see if I can make email unique!
UsernameAttributes: ['email']
Now you can run amplify push
NOTE: there are now settings for configuring this using the amplify-cli.
The hosted UI still needs to be setup:
-
AWS Console > Cognito > Manage user pools > click on a specific user pool
-
App integration > Domain name: https://<domain_prefix>.auth.us-east-1.amazoncognito.com OR setup your own custom domain
-
Federation > Identity providers > Facebook - go to https://developers.facebook.com > My Apps > Settings > Basic to find app id, secret, and set Authorize scope to "public_profile,email"
-
Federation > Identity providers > Google - go to Google dev console https://console.developers.google.com/projectselector2/apis/credentials?authuser=1 and get client_id, secret, and set Authorize scope to "profile email openid"
-
Federation > Attribute mapping > Facebook: email -> email, name -> name, first name -> given name, verified -> email verified
-
Federation > Attribute mapping > Google: email -> email, name -> name, given name -> given name, email verified -> email verified
-
App client settings (for both clients)
- Select all identity providers
- Sign in and sign out URLs:
- <url_in_your_app_that_hosted_ui_loads_after_signing_in>
- <url_in_your_app_that_hosted_ui_loads_after_signing_out>
- Allowed OAuth Flows: "Authorized code grant"
- Allowed OAuth Scopes: email, openid, aws.cognito.signin.user.admin, profile
-
Update the redir for both FB and Google apps to support the URL from step 1, e.g., "https://<domain_prefix>.auth.us-east-1.amazoncognito.com/oauth2/idpresponse" OR your own custom domain
- Facebook:
- Products > Facebook Login > Settings > Valid Oauth Redirect URIs: https://<domain_prefix>.auth.us-east-1.amazoncognito.com/oauth2/idpresponse
- Google:
- Authorized JavaScript origins: https://<domain_prefix>.auth.us-east-1.amazoncognito.com
- Authorized redirect URIs: https://<domain_prefix>.auth.us-east-1.amazoncognito.com/oauth2/idpresponse
- Facebook:
-
Update
App.js
or wherever theApp.configure({ oauth })
call is performed such that theoauth
object has:- domain: https://<domain_prefix>.auth.us-east-1.amazoncognito.com OR your own custom domain
- Emails are case-sensitive, there is no way to change this. This matches the official spec for email, but it does not match how every popular websites works on the Internet. Add a preSignUp lambda trigger that does a Cognito listUsers query for
{ Filter: 'email = "' + email + '"', UserPoolId: userPoolId }
to prevent people from signing up with variants of the same email. This also means user's could get into a funny state with a case they don’t expect for their email (you’ll have to edit it for them ). Additionally, I don’t see a way to merge a social login with an email login. - Setup application to handle the sign in and sign out URLs, e.g., React component (maybe a provider) that has a Hub listener (onHubCapsule) to listen for "auth" channel and events "signIn" or "signIn_failure" to know to set whether the current user is signed in or not.
- Do the UI customization. (NOTE: the get-ui-customziation and set-ui-customization API offers some extra options beyond what the AWS console UI offers)