Create sign-in page in Cognito user pool

TOC

Configure the hosted UI of the Cognito user pool to create a sign-in page

Create a sign-in page using Cognito.

Cognito is an authentication system service provided by AWS.

Amazon Cognito provides authentication, authorization, and user management for your web and mobile apps. Your users can sign in directly with a user name and password, or through a third party such as Facebook, Amazon, Google or Apple.

What is Amazon Cognito?

This time, we will use the hosted UI of the Cognito user pool to create a sign-in page.

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.

Using the Amazon Cognito hosted UI for sign-up and sign-in

In this article, we will build an environment that follows the contents of the AWS official website Setting up the hosted UI with the Amazon Cognito console.

Environment

Diagram of creating sign-in page in Cognito user pool with CloudFormation

Create a Cognito user pool. Use the user pool to create a sign-in/sign-up function and a page for this function.

Configure the user pool to register the following information when signing up

  • Email address
  • Password
  • Name * not username

Sign-in will be performed using the email address and password.

Create an S3 bucket, enable the static website hosting feature, and install the following three HTML files.

  • index.html: for the top page
  • signin.html: For the page to be displayed after signing in
  • signout.html: For the page to be displayed after signing out

CloudFormation template files

We will build the above configuration using CloudFormation.

Place the CloudFormation template at the following URL.

https://github.com/awstut-an-r/awstut-fa/tree/main/010

This time, we will build this environment with a nested stack. For more information about nested stacks, please refer to the following page.

あわせて読みたい
CloudFormation’s nested stack 【How to build an environment with a nested CloudFormation stack】 Examine nested stacks in CloudFormation. CloudFormation allows you to nest stacks. Nested ...

Template file points

We will cover the key points of each template file to configure this environment.

Create user pool

In fa-010-cognito.yaml, we will define the Cognito-related resources.

First, let’s check the user pool itself.

Resources:
  UserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      AutoVerifiedAttributes:
        - email
      UsernameAttributes:
        - email
      UserPoolName: !Sub ${Prefix}-UserPool
      Schema:
        - AttributeDataType: String
          Mutable: true
          Name: name
          Required: true
Code language: YAML (yaml)

The AutoVerifiedAttributes property allows you to set automatic verification for the specified attributes.

Amazon Cognito can automatically verify email addresses or mobile phone numbers by sending a verification code—or, for email, a verification link. For email addresses, the code or link is sent in an email message. For phone numbers, the code is sent in an SMS text message.

Configuring email or phone verification

You can specify “email” or “phone_number” for this property. In this case, we will specify the former so that a verification code will be automatically sent to the registered email address upon signup.

The UsernameAttributes property is a parameter to specify the attributes to be used in place of the user name (username).

UsernameAttributes
Determines whether email addresses or phone numbers can be specified as user names when a user signs up. Possible values: phone_number or email.

AWS::Cognito::UserPool UsernameAttributes

As mentioned above, you can specify “email” or “phone_number” for this property, but we will specify the former. In this case, we will specify the former. This setting will allow users to sign in using their email address instead of their user name.

One thing to note about this property is that username is considered a required attribute in Cognito.

The username value is a separate attribute and not the same as the name attribute. A username is always required to register a user, and it can’t be changed after a user is created.

User pool attributes

However, if a username is not required, such as in the case of the application we are creating this time, an email address/phone number can be used instead of a username. In this case, the user name will be set to a randomly generated ID.

If your application does not require a username, you do not need to ask users to provide one. Your app can create a unique username for users in the background. This is useful if, for example, you want users to register and sign in with an email address and password.

User pool attributes

The Schema property allows you to specify the attributes to be registered when signing up. In this case, we will add one of the standard attributes, name (not username).

Note that email address and password are not required to be specified in this property, as they are set to “email” in the UsernameAttributes property.

Create user pool app client

Next, check the user pool app client.

Resources:
  UserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      AccessTokenValidity: 60 # (minutes) default value.
      AllowedOAuthFlowsUserPoolClient: true
      AllowedOAuthFlows:
        - code
        - implicit
      AllowedOAuthScopes:
        - aws.cognito.signin.user.admin
        - email
        - openid
        - phone
        - profile
      CallbackURLs:
        - !Sub "${BucketWesSiteEndpointUrl}/${SigninHtml}"
      ClientName: !Sub ${Prefix}-UserPoolClient
      EnableTokenRevocation: true # default value.
      ExplicitAuthFlows:
        - ALLOW_CUSTOM_AUTH
        - ALLOW_REFRESH_TOKEN_AUTH
        - ALLOW_USER_SRP_AUTH
      IdTokenValidity: 60 # (minutes) default value.
      LogoutURLs:
        - !Sub "${BucketWesSiteEndpointUrl}/${SignoutHtml}"
      PreventUserExistenceErrors: ENABLED # default value.
      RefreshTokenValidity: 30 # (days) default value.
      SupportedIdentityProviders:
        - COGNITO
      TokenValidityUnits:
        AccessToken: minutes
        IdToken: minutes
        RefreshToken: days
      UserPoolId: !Ref UserPool
Code language: YAML (yaml)

By creating an app client, you will be able to perform API operations such as signup.

An app is an entity within a user pool that has permission to call unauthenticated API operations.

Configuring a user pool app client

We will configure the app client settings in a manner similar to the AWS official page Using the Amazon Cognito hosted UI for sign-up and sign-in.

The parameters that are important this time are the CallbackURLs and LogoutURLs properties. Specify the URLs to be redirected to after sign-in and sign-out, respectively.

Enter Callback URL(s). A callback URL indicates where the user will be redirected after a successful sign-in.

Enter Sign out URL(s). A sign-out URL indicates where your user will be redirected after signing out.

Using the Amazon Cognito hosted UI for sign-up and sign-in

In this case, we will specify the URL of the HTML file to be placed in the S3 bucket as described below.

Set up domain

Then, check the domain.

Resources:
  UserPoolDomain:
    Type: AWS::Cognito::UserPoolDomain
    Properties:
      Domain: !Ref Prefix
      UserPoolId: !Ref UserPool
Code language: YAML (yaml)

You need to create a domain for the sign-in/sign-up page with hosted UI.

After setting up an app client, you can configure the address of your sign-up and sign-in webpages. You can use an Amazon Cognito hosted domain and choose an available domain prefix, or you can use your own web address as a custom domain.

Configuring a user pool domain

This time, we will use the domain prefix to set the domain, passing the prefix string to the Domain property. For the Tokyo region (ap-northeast-1), the domain containing the prefix will be as follows

  • [prefix].auth.ap-northeast-1.amazoncognito.com

The URL for the sign-in/sign-out page with the hosted UI is as follows

  • URL for sign-in page
    • https://[prefix].auth.ap-northeast-1.amazoncognito.com/login?response_type=code&client_id=[app-client-id]&redirect_uri=[callback-url]
  • URL for sign-out page
    • https://[prefix].auth.ap-northeast-1.amazoncognito.com/logout?response_type=code&client_id=[app-client-id]&logout_uri=[sign-out-url]

Please note that there are restrictions on the URLs that can be specified as sign-in/sign-out destinations, and they must start with “https”.

Prepare sign-in/sign-out destination content with S3 static website hosting

Define S3-related resources in fa-010-s3.yaml.

Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref Prefix
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
        BlockPublicPolicy: false
        IgnorePublicAcls: false
        RestrictPublicBuckets: false
      WebsiteConfiguration:
        IndexDocument: index.html

  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref Prefix
      PolicyDocument:
        Statement:
          Action:
            - s3:GetObject
          Effect: Allow
          Resource: !Sub "arn:aws:s3:::${S3Bucket}/*"
          Principal: "*"
Code language: YAML (yaml)

We will prepare the content to be displayed after sign-in and sign-out. We will use the static website hosting feature provided by S3.

You can use Amazon S3 to host a static website. On a static website, individual webpages include static content. They might also contain client-side scripts.

Hosting a static website using Amazon S3

For more information, please see the following page.

あわせて読みたい
Publish your site with S3 static website hosting 【Configure the S3 static website hosting to publish your site】 Find out how to use the S3 static website hosting to publish a website. If your website cons...

The content published using this function can be accessed via two types of endpoints (website endpoint and RESTAPI endpoint), but we will use the REST API endpoint. This has to do with the URL to be specified as the sign-in/sign-out destination as described earlier. This is because REST API endpoints are the endpoints that can be used for HTTPS communication, which is a condition of the URLs that can be specified. In the case of the Tokyo region (ap-northeast-1), the URL to access the content using this endpoint is as follows

https://s3-ap-northeast-1.amazonaws.com/[バケット名]/[オブジェクト名]

Architecting

We will use CloudFormation to build this environment and check its actual behavior.

Create CloudFormation stacks and check resources in stacks

Create a CloudFormation stacks.

For more information on how to create stacks and check each stack, please refer to the following page.

あわせて読みたい
CloudFormation’s nested stack 【How to build an environment with a nested CloudFormation stack】 Examine nested stacks in CloudFormation. CloudFormation allows you to nest stacks. Nested ...

After checking the resources for each stack, the information for the main resource created this time is as follows

  • Name of the S3 bucket: fa-010
  • ID of Cognito user pool: ap-northeast-1_Ajzqt7Te7
  • Cognito user pool app client ID: 5vb5gkv9rjeunvendcc1pj4089
  • Cognito user pool domain prefix: fa-010

From the above, the URL for the sign-in/sign-out page with the hosted UI mentioned above is determined as follows

  • URL for sign-in page
    • https://fa-010.auth.ap-northeast-1.amazoncognito.com/login?response_type=code&client_id=5vb5gkv9rjeunvendcc1pj4089&redirect_uri=https://s3-ap-northeast-1.amazonaws.com/fa-010/signin.html
  • URL for sign-out page
    • https://fa-010.auth.ap-northeast-1.amazoncognito.com/logout?response_type=code&client_id=5vb5gkv9rjeunvendcc1pj4089&logout_uri=https://s3-ap-northeast-1.amazonaws.com/fa-010/signout.html

Place the HTML in the S3 bucket

Place the HTML in the S3 bucket and prepare the contents after sign-in/sign-out.

Put the sign-in/sign-out URL described above in index.html, and then install it using the AWS CLI.

$ aws s3 cp ./html s3://fa-010/ \
--recursive
upload: ./html/index.html to s3://fa-010/index.html
upload: ./html/signout.html to s3://fa-010/signout.html
upload: ./html/signin.html to s3://fa-010/signin.html
Code language: Bash (bash)

Accessing the hosted UI: Sign up

Now that we are ready, let’s actually access the hosted UI.

First, access the following URL

https://s3-ap-northeast-1.amazonaws.com/fa-010/index.html

The root page, index.html, will be displayed.

Access the sign in page after signing up.

Click on “Sign In”. This is the link to the sign-in URL.

Click on the link to the Sign up page.

At this time, we have not created a user for sign-in. Therefore, click on “Sign up” to create a user.

Register an account with the hosted UI.

In addition to Email and Password, you will now see a form to enter Name. This is an additional attribute that we specified when we created the user pool. In this case, we will register with the name “awstut”.

After entering the appropriate values, click “Sign up”.

Enter the authentication code.

An authorization code entry form will appear. The code will be sent to the email address you entered earlier, so enter it here.

The authentication code has been sent to you by email.

This time it was “921303”.

After entering the code in the previous form, click “Confirm Account” to validate the account.

You can check the information about the created user from the following command.

$ aws cognito-idp list-users \
--user-pool-id ap-northeast-1_Ajzqt7Te7 \
--filter "name='awstut'"
{
    "Users": [
        {
            "Username": "29c9a15d-9749-490c-83d9-ffbfd29392a6",
            "Attributes": [
                {
                    "Name": "sub",
                    "Value": "29c9a15d-9749-490c-83d9-ffbfd29392a6"
                },
                {
                    "Name": "email_verified",
                    "Value": "true"
                },
                {
                    "Name": "name",
                    "Value": "awstut"
                },
                {
                    "Name": "email",
                    "Value": "[email-address]"
                }
            ],
            "Enabled": true,
            "UserStatus": "CONFIRMED"
        }
    ]
}
Code language: Bash (bash)

You can see that the required attribute, username, is set to an auto-generated ID.

Accessing the hosted UI: Sign in

Your account has been created by the above procedure.

After accessing the top page (index.html) again, click the “Sign In” link.

Enter your email address and password on the hosted UI page.

After entering your email address and password, click “Sign In”.

After successfully authenticating on the sign in page.

The sign-in process was successful, and the redirected site, signin.html, is now displayed.

Accessing the hosted UI: Sign out

Finally, go back to the top page and click on the “Sign Out” link.

This is the link to the sign-out URL.

Page after signing out.

The sign-out process was successful, and the redirected page, signout.html, was displayed.

Summary

We have confirmed that we can easily implement authentication system functions by using the Cognito user pool and hosted UI.

TOC