The Amazon Cognito Hosted UI provides you an OAuth 2.0 compliant authorization server. It includes default implementation of end user flows such as registration and authentication. You can also customize user flows, such as the addition of Multi Factor Authentication (MFA), by changing your user pool configuration.
The Hosted UI allows end-users to login and register directly to your user pool, through Facebook, Amazon, and Google, as well as through OpenID Connect (OIDC) and SAML identity providers. The Amplify CLI will setup and configure a Hosted UI for you when adding Authentication to your app.
Sign in to the Amazon Cognito console . In the navigation pane, choose User Pools, and choose the user pool you want to edit. Choose the App integration tab. To customize UI settings for all app clients, locate Hosted UI customization and select Edit.
Amazon Cognito is our identity management solution for developers building B2C or B2B apps for their customers, which makes it a customer-targeted IAM and user directory solution. AWS SSO is focused on SSO for employees accessing AWS and business apps, initially with Microsoft AD as the underlying employee directory.
I also struggled with this; I agree that the documentation is a little light.
The link you provided shows what your Cognito UI URL might look like:
https://<your_domain>/login?response_type=code&client_id=<your_app_client_id>&redirect_uri=<your_callback_url>
The idea is that you send your user to this URI, they do their business, and then they get redirected back to you with some sort of token(s) or code. You can check your domain by clicking "Domain name" in the left nav bar.
App Client Settings and OAuth Grant Types
First, check your App client settings. You'll need to whitelist your Callback URL(s) (where Cognito will redirect back to), and make sure at least one OAuth Flow is allowed.
Cognito App client settings
"Authorization code grant" will return an authorization code, which you then send to the oauth2/token
endpoint to get an access_token, id_token, and refresh_token. This is a good choice if you have a back-end application and want refresh tokens.
"Implicit grant" is what I'm using in my front-end application. It will return an access token and an id token directly to my front-end app.
To use implicit grant, change response_type=code
to response_type=token
in your Cognito UI URL.
Implicit Grant Example
So if your redirect after successful authentication looks like this:
https://localhost:3000/#access_token=eyJraWQiOiJG...&id_token=eyJraWQZNg....&token_type=Bearer&expires_in=3600
You just need to peel the id_token off the URL and send it to Cognito, with your User Pool as the key in the Logins map. In Javascript:
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:bxxxxxx6-cxxx-4xxx-8xxx-xxxxxxxxxx3c',
Logins: {
'cognito-idp.us-east-1.amazonaws.com/us-east-1_ixxxxxxx': idToken
}
});
Where idToken
is the id token that came back to you on the redirect.
Authorization Code Grant Type
If you use authorization code grant type instead (response_type=code), your back end will need to call the /oauth2/token
endpoint to exchange the code for tokens. That call would look something like this:
curl -X POST \
https://<my-cognito-domain>.auth.us-east-1.amazoncognito.com/oauth2/token \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code&scope=email%20openid%20profile&redirect_uri=https%3A%2F%2Flocalhost%3A3000%2F&client_id=15xxxxxxxxxxxxxx810&code=54826355-b36e-4c8e-897c-d53d37869ee2'
Then you can give this id token to Cognito as above.
UI Notes
My application is popping up the Cognito UI in a new tab when the user clicks a link. When the redirect comes back to my app, I use postMessage()
to send the tokens to the parent window, which then closes the new tab. I think this is a relatively common pattern.
I haven't tried it, but I'm guessing rendering the UI into an iframe is disallowed, as a mitigation against click-jacking. Source
I hope this is at least somewhat helpful. Good luck!
I implemented this flow, not using Amplify, just using Cognito Hosted UI:
My site process the tokens: The trick is to create an Auth instance, this one can parse the hash and create the user on the LocalStorage:
// mysite.com/login
import {CognitoAuth} from 'amazon-cognito-auth-js';
// Configuration for Auth instance.
var authData = {
UserPoolId: 'us-east-1_xxxx',
ClientId: '1vxxxxx',
RedirectUriSignIn : 'https://example.com/login',
RedirectUriSignOut : 'https://example.com/logout',
AppWebDomain : 'example.com',
TokenScopesArray: ['email']
};
var auth = new CognitoAuth(authData);
//Callbacks, you must declare, but can be empty.
auth.userhandler = {
onSuccess: function(result) {
},
onFailure: function(err) {
}
};
//Get the full url with the hash data.
var curUrl = window.location.href;
//here is the trick, this step configure the LocalStorage with the user.
auth.parseCognitoWebResponse(curUrl);
window.top.close();
After the user has been set in the Local Storage, the callback(tab 2) is closed.
On my site (tab 1) I configure an EventListener to listen if there is a change in the Local Storage.
constructor() {
window.addEventListener('storage', this.userLogged);
}
userLogged(event) {
if (event.key.indexOf('CognitoIdentityServiceProvider') !== -1) {
var data = {
UserPoolId: 'us-east-1_xxxxx',
ClientId: 'xxxxx'
};
var userPool = new CognitoUserPool(data);
//behind the scene getCurrentUser looks for the user on the local storage.
var cognitoUser = userPool.getCurrentUser();
}
}
That use case, putting Cognito in front of S3, using the hosted UI, is covered in this AWS blog: https://aws.amazon.com/blogs/networking-and-content-delivery/authorizationedge-using-cookies-protect-your-amazon-cloudfront-content-from-being-downloaded-by-unauthenticated-users/
The blog contains sample code you can steal from. And you can deploy the sample solution easily using the serverless application repository.
Disclaimer: I authored that blog. Hope it can be of use to you!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With