How to Set Up Alexa Account Linking with Amazon Cognito User Pools to Create a Personalized Customer Experience

Michael Griffiths Nov 08, 2019
Share:
Build Tips & Tools CLI Tutorial Personalization Developer Console
Blog_Header_Post_Img

Introduction

In part one of this blog series, we reviewed the different options for personalizing your skill’s experience through the use of the Customer Contact, Device Location, Device Settings, and Location Services APIs, as well as through account linking.

This tutorial guides you through the creation and configuration of an Amazon Cognito User Pool and provides sample skill code which will be configured to make use of the Cognito User Pool as an OAuth authorization and service end-point. During this walk through, we'll go over:

  • Setting up of an Amazon Cognito User Pool with custom attributes
  • Creating an AWS IAM Role to allow the AWS Lambda function to access Amazon Cognito
  • Creating an Alexa skill configured with Account Linking
  • Creating an AWS Lambda function to power your skill

If the Cognito feature of additional user attributes/properties is not required, consider using Login with Amazon.

Sample Skill

The Linked Profile sample custom skill demonstrates account linking for the purposes of utilizing a linked profile. While any compliant OAuth identity provider could be used with account linking, this sample will use Amazon Cognito.

These instructions will cover how to set up a user account and OAuth service using Amazon Cognito User Pools, coupled with an example skill (written using the Alexa Skills Kit (ASK) SDK and AWS SDK for Node.js) that links to the Cognito OAuth service and provides personalized responses.

This sample is a starting point for skill developers who may not have existing user accounts or OAuth infrastructure already in place.

Note: The Amazon Cognito configuration provided in this tutoral does not constitute a full solution for user account management and OAuth.

Prerequisites

In order to completely set up this sample, the following are required:

  1. An AWS account which can:
    • Create Amazon Cognito User Pools
    • Create AWS IAM roles
    • Create AWS Lambda functions
    • Create and update DynamoDB tables
    • Create CloudWatch logs
  2. An Amazon Developer account.
  3. Your developer account's vendor ID. To find your vendor ID, go to https://developer.amazon.com/settings/console/mycid and sign in with your Amazon Developer account if prompted. Once you have it, copy it to your Scratch-Pad.
    • What's a Scratch-Pad? In addition to your vendor ID, there will be a number of values you will obtain from one step and then need to use at a later time. We recommend creating a new text file using your favorite text editor to use as a "scratch pad." We will refer to this text file as the Scratch-Pad.
  4. (Optional) Domain, optionally hosted in Amazon Route53
    • Note: If you will be creating a linked skill for testing or demo purposes only, access to a domain is not required. If you are creating something for production use, you will need the ability to create a domain name that can be used by Amazon Cognito.

Architecture

Amazon Cognito User Pool

interaction model graphic

How the Amazon Cognito User Pool works:

  1. The Alexa service manages the refresh tokens and obtains new access tokens as they expire.
  2. A current, valid Access Token is provided at run time to your skill code by the Alexa Service.
  3. Your skill code uses that token to access the user’s profile in the User Pool.

Customers will authenticate directly with the Cognito user portal when linking the skill using the Alexa app. The specific sequence of events which happen when the account linking process happens is shown in the following diagram.

account linking model graphic

How Account Linking works with Amazon Cognito User Pools:

  1. When the customer initiates Account Linking (either from a card sent by the skill or when enabling the skill through the Alexa Skills Store), the authorization link specified by the developer is opened by the app. In this case, it is a link to the Cognito User Portal.
  2. Once redirected, the customer interacts with the Cognito login page, providing the necessary username and password in order to authenticate.
  3. Once Cognito verifies the customer’s credentials, it provides an authorization code to the app, which passes that to the Alexa Service.
  4. The Alexa Service then provides that code to Cognito to obtain the initial Access Token and Refresh Token.

Step-by-Step Instructions

Create the User Pool

  1. Log in to the AWS Management Console and navigate to the Cognito service. Click here to go directly there.
  2. Check the AWS region being used by looking in the upper right of the AWS Management Console. Change it if desired.
    • Note: You can use any region supported by Cognito. However, we recommend that you use one of the four regions that supports the Alexa Skills Kit trigger so you can keep all the related resources in the same region. Those four regions are us-east-1 (N. Virginia), us-west-2 (Oregon), eu-west-1 (Ireland) and ap-northeast-1 (Tokyo). If necessary, switch to your desired region.
  3. Click Manage User Pools.
  4. Click Create a user pool.
    • For the purposes of this sample, only the minimum required settings are being changed. For production use, be sure to review each section and update accordingly.
  5. Enter a Pool name, such as “Alexa Skill Users,” and click Review Defaults.
  6. Select Attributes on the left-side menu.
  7. Select Email address or phone number and choose Allow email addresses.
  8. In the Which standard attributes do you want to require? section, check the following:
    • Address
    • Email
    • Family name
    • Given name
    • Phone number
  9. Click Next Step.
  10. Select MFA and verifications on the left-side menu and set:
    • Do you want to enable Multi-Factor Authentication (MFA) to Off
    • Which attributes do you want to verify? to Email
  11. Click Save Changes.
  12. Select App clients on the left-side menu, then click Add an app client.
  13. Enter an App client name such as “AlexaDemoSkill.”
  14. Enter 3650 in the Refresh token expiration (days) field.
    • Note: For Alexa account linking, it is best practice to have refresh tokens that do not expire. Amazon Cognito allows a maximum expiry time of 3650 days (10 years), so we will use that maximum.
  15. Ensure that the Generate client secret box is checked. (The remaining boxes should be un-checked.)
  16. Click Create App Client.
  17. Select Review on the left-side menu and click Create pool at the base of the page. Once created, you will be presented with a message saying Your user pool was created successfully.
  18. The left-side menu will have changed. Select General settings > App clients on the left-side menu, and select Show Details.
  19. Copy the App client id and App client secret to your Scratch-Pad.
  20. Select App integration > App client settings on the left-side menu. Under Enabled Identity Providers, check the box next to Cognito User Pool.
  21. Next, construct the Callback URL list.
    • In our Scratch-Pad, replace the placeholder value [VID] in these URLs with your vendor ID (which you should find in your Scratch-Pad): 

Copied to clipboard
https://alexa.amazon.co.jp/api/skill/link/[VID]
Copied to clipboard
https://layla.amazon.com/api/skill/link/[VID]
Copied to clipboard
https://pitangui.amazon.com/api/skill/link/[VID]

  • Note: These three URLs correspond to the three Alexa regions: FE (co.jp), EU (layla), NA (pitangui). 
  • Combine them into a single comma-seperated value. For example, if your vendor ID is M12AB34CD56EF7, the result would be:

Copied to clipboard
https://alexa.amazon.co.jp/api/skill/link/M12AB34CD56EF7,https://layla.amazon.com/api/skill/link/M12AB34CD56EF7,https://pitangui.amazon.com/api/skill/link/M12AB34CD56EF7

22. Copy/paste the comma-separated Callback URL list into the Callback URL(s) field.

23. Further down the same page, under OAuth 2.0 and Allowed OAuth Flows, check the box titled Authorization code grant.

24. Under Allowed OAuth Scopes, check these boxes:

openid

The openid scope returns all user attributes in the ID token that are readable by the client. The ID token is not returned if the openid scope is not requested by the client.

aws.cognito.signin.user.admin

The aws.cognito.signin.user.admin scope grants access to Amazon Cognito User Pool API operations that require access tokens.

profile

The profile scope grants access to all user attributes that are readable by the client. Note: Phone and email are included in the profile scope, so there’s no need to check these boxes.

      25. Click Save changes.

Set up Cognito OAuth Domain

There are two options for setting your Cognito OAuth domain:

  • Use a Cognito Domain: This option can only be used for trial and demonstration purposes.
  • Use Your Own Domain: This option is required if you intend to publish a skill that makes use of this Cognito pool.

Note: You need to own the OAuth domain if you wish to publish a skill (or skills) that uses this OAuth system.

Use a Cognito Domain

Since you are just trying this out, you can use a Cognito domain.

  1. Select App integration > Domain name from the left-side menu.
  2. Chose a domain prefix (e.g. myoauth) and enter it into the Domain Prefix field.
    • Note: The domain prefix has to be unique in the chosen AWS region.
  3. Click Check availability.
  4. If the domain prefix is not available, pick a new one and repeat the checking process.
  5. Once you have found an available domain prefix, click Save changes.
  6. Select App integration from the left-side menu.
  7. Copy the full URL (e.g. https://myoauth.auth.us-west-2.amazoncognito.com) shown in the Domain field to your Scratch-Pad.

Use Your Own Domain

If you are unsure about the management of SSL certificates for your domain, contact your network administrator. This sample assumes you have a domain managed by Amazon Route 53. Domains managed elsewhere may have different steps, which are outside the scope of this sample.

  1. Select App integration > Domain name from the left-side menu.
  2. Click Use your domain. If you don’t have any existing managed certificates, then you will see the message We didn't find any AWS managed certificates for this region. To add one, click here.
    1. Select click here to start the Amazon Certificate Manager (ACM) creation process.
    2. Verify you are in the us-east-1 region for this step. If not, switch to it.
    3. On the Certificates Manager console, click Request a certificate.
    4. Select Request a public certificate.
    5. Click the Request a certificate button.
    6. Enter your domain name, such as auth.mydomain.com, in the Domain name entry field and click Next.
    7. Select DNS validation and click Review.
      • Note: If you don't have the necessary permissions to use this method, choose Email validation instead.
    8. On the next screen, click Confirm and request.
    9. Click Continue.
      • Note: Add a CNAME to your domain using the details provided. This process will vary depending on the domain hosting provider which you are using (for example, Route 53). For Route 53 hosted zones, continue with this section.
    10. Expand the Domain entry for the domain you created and is pending validation. Click Create record in Route 53
    11. Review the details and then click Create.
      • Note: It can take 30 minutes or longer for the changes to propagate and for AWS to validate the domain and issue the certificate.
    12. Once the certificate is validated, return to the Cognito console and the region in which you created your User Pool.
    13. Enter the Domain Name and select the AWS Managed Certificate.
    14. Click Save Changes.
    15. Copy the Alias Target to your Scratch-Pad.
    16. Create the alias record in Route53.
      1. Navigate to the Route53 console.
      2. Click on Hosted zones.
      3. Click on your domain.
      4. Click on Create Record Set.
      5. Enter the subdomain into the Name field.
      6. Set the type to A - IPv4 address.
      7. Set Alias to Yes.
      8. Paste the Alias Target from your Scratch-Pad to the Alias Target field.
      9. Click Create.
    17. Return to the Cognito console.
    18. Select App integration from the left-side menu.
    19. Copy the full URL (e.g. https://auth.mydomain.com) shown in the Domain field to your Scratch-Pad.

You have now created a User Pool and are ready to move on to the next step of creating the AWS IAM role which will be used by the AWS Lambda function that backs your skill.

AWS IAM Setup

In this section, you will create an AWS IAM Role (with policy) which will be used by the Lambda function that backs your skill.

  1. Navigate to the AWS IAM Console.
  2. Click Policies on the left-side menu.
  3. Click the Create Policy button.
  4. Click on the JSON tab.
  5. Replace the placeholder JSON with the following:

Copied to clipboard
{

"Version": "2012-10-17",

"Statement": [

{

"Effect": "Allow",

"Action": [

"cognito-idp:GetUser",

"logs:CreateLogGroup",

"logs:CreateLogStream",

"logs:PutLogEvents"

],

"Resource": "*"

}

]

}

6. Click Review Policy.

7. Enter a name such as linked-profile-skill-policy.

8. Click Create policy.

9. Select Roles on the left-side menu.

10. Click the Create role button.

11. Under Select type of trusted entity, select AWS service.

12. Under Choose the service that will use this role, select Lambda.

13. Click the Next:Permissions button.

14. Search for the policy (linked-profile-skill-policy) created in an earlier step and check the box next to your policy.

15. Click the Next:Tags button, then the Next:Review button.

16. Enter a name such as linked-profile-role.

17. Click the Create role button.

18. Copy the role name to your Scratch-Pad. You will need this later in the process.

Alexa Skill Setup

In this section, you will create a skill configured to support account linking with the Cognito system created earlier.

Create Skill

  1. Log in to the Alexa Skills Kit developer console using your Amazon Developer account: https://developer.amazon.com/alexa/console/ask
  2. From the Alexa Skills Kit developer console, click Create Skill.
  3. Specify the basic settings for your skill:
    • Enter a skill name such as Linked Profile Sample.
    • Select one of the supported locales (English-AU, English-US or English-UK).
    • Select the Custom interaction model.
    • Select Self Hosted.
  4. Select the Start from scratch template.
  5. Click the Create a skill button on the top-right.
  6. Select Interaction Model > JSON Editor on the left-side menu. Select the corresponding model for your locale from the models folder. (For example: For English-AU, use en-AU.json). Either drag/drop the file into the area of the JSON Editor that says Drag and drop a .json file, or copy/paste the contents of the file, being sure to replace the entirety of the existing interaction model.
  7. Click the Save Model and then the Build Model buttons.

Create AWS Lambda Function

  1. Create an AWS Lambda function using the premium facts skill application as a template.
    1. Start the creation process by clicking here.
    2. Update the Application name to Linked-Profile-Sample-Skill.
    3. Update the SkillDescription field.
    4. Update the SkillFunctionName to ask-linked-profile.
    5. Click Deploy.
    6. Once the application has been deployed, click on SkillFunctionResource link.
  2. Scroll down to the Function Code section.
  3. Replace the contents of the index.js file with the contents of the index.js from this repo.
  4. Scroll down to the Environment variables section.
  5. If your Cognito User Pool was not created in the us-east-1 (N. Virginia) region, create an environment variable named COGNITO_REGION.
    1. In the Key field, enter COGNITO_REGION.
    2. In the Value field, enter the corresponding region code (e.g. us-east-1):
      • For N. Virginia, enter us-east-1
      • For Oregon, enter us-west-2
      • For Tokyo, enter ap-northeast-1
      • For Ireland, enter eu-west-1
  6. Scroll down to the Execution Role section.
  7. Set the Execution Role to the role name that you created previously (for example, linked-profile-role).
  8. Select Save at the top of the page.
  9. Copy the full function ARN to your Scratch-Pad.
  10. Leave the Lambda console open as you can come back to restrict the function to be used by just your skill.

Connect the Skill with the Lambda Function

  1. Select Endpoint on the left-side menu and select the AWS Lambda ARN circle.
  2. Enter the Lambda function ARN (copied to the Scratch-Pad) into the Default Region field.
    • Note: If you attempt to save the endpoint pointing to the Lambda function before a valid Alexa Skill Kit trigger has been added to the function, you will see a "Save Failed" error stating "The trigger setting for the Lambda {arn} is invalid." Simply continue with adding the trigger and save it after adding the skill ID.
  3. Copy Your Skill ID (click the Copy to Clipboard link) and go back to the Lambda console, leaving the developer portal tab/browser open.
  4. If there is an existing Alexa Skills Kit trigger, click it, then click the Delete button.
  5. Under Add triggers on the left-side, select Alexa Skills Kit.
  6. Scroll down and find the Skill ID field, and paste in the skill ID from your clipboard.
  7. Ensure that the Enable option is selected and then click the Add button.
  8. Click Save near the top-right of the Lambda console.
  9. Go back to the Alexa developer console and select the Save Endpoints button.
  10. Select JSON Editor on the left-side menu and then select the Build Model button at the top (next to Save Model). When the build is finished, move to next step.

Configure Account Linking for the Skill

  1. Select ACCOUNT LINKING on the left-side menu and change the slider switch to on.
    • In most scenarios, you will also enable the setting Allow users to enable skill without account linking. This will allow customers to engage with your skill prior to being required to either link or create an account for it. In our case, there is no meaningful functionality if the account is not linked, so we are not enabling this option.
  2. Select Auth Code Grant for Authorization Grant Type.
  3. For Authorization URI, replace <example_domain> with your domain and <VID> with your in vendor ID the following URL: https://<example_domain>/oauth2/authorize?redirect_url=https://pitangui.amazon.com/api/skill/link/<VID>
  4. The domain and vendor ID should be saved in your Scratch-Pad. The example Authorization URL for the domain of myoauth and vendor ID of M12AB34CD56EF7 would be: https://myoauth.auth.us-east-1.amazoncognito.com/oauth2/authorize?redirect_url=https://pitangui.amazon.com/api/skill/link/M12AB34CD56EF7
  5. For Access Token URI, replace <your_domain> with your domain in the following URL: https://<example_domain>/oauth2/token
    • For example, if you specified "myoauth" as your Cognito domain, the Access Token URI would be: https://myoauth.auth.us-east-1.amazoncognito.com/oauth2/token
  6. For Client ID and Client Secret, enter the corresponding values that you saved in your Scratch-Pad.
  7. Leave Client Authentication Scheme as HTTP Basic (Recommended).
  8. Click + Add scope and enter openid.
  9. Click + Add scope and enter profile.
  10. Click + Add scope and enter aws.cognito.signin.user.admin.
  11. Click + Add domain and enter your domain name stored in your Scratch-Pad.
  12. Important! Do not include the https:// in the Domain List value, just include the domain.
  13. Click the Save button on the top-right and you are done.

Try It Out

Create a Test User

The simplest way to create a user is to do so via the account linking process in the Alexa website.

  1. Log in to the Alexa website for your region (for example, alexa.amazon.com) using the same developer.amazon.com account in which you have created the skill.
    • Note: You can also do this using the Alexa app on your phone.
  2. Navigate to your skill's detail page.
    1. Click on Skills.
    2. Click Your Skills.
    3. Click on the DEV SKILLS tab.
    4. Find the skill you created and click on it.
  3. Click Enable. If already enabled, click Settings and then click Link Account.
  4. A new browser tab will open. Create the user by:
    1. Click Sign up at the base of the login window. This will convert the form into a Cognito account sign-up page.
      • Note: This form's style and branding can be changed from the Amazon Cognito console. Make the changes in the App integration > UI customization section.
    2. Enter an email, address, phone number (including country code), given name, and family name.
      • The email address can be fake, as you can enable the account using the Cognito console. If you use a real email (that you have access to), then you will receive a verification email. It can take a few minutes to arrive, so rather than waiting we'll use the console instead. The verification email can be customized using the Amazon Cognito console. Make changes in the General settings > Message customizations section.
    3. Enter a password.
      • Note: The password policy is configurable from the Amazon Cognito console. Adjust the policy from the General settings > Policies section.
    4. Click Sign up.
    5. At this point, you will be asked to enter a verification code. If you don't want to wait for the verification email (or you don't have access to the email sent to that address), you can close this browser tab and move to the next section as you can verify the account through the Cognito console.
    6. Enter the verification code and click Verify.

Confirm the Test User and Finish Account Linking

If you verified the test account using the verification code, skip to the next section.

  1. Check that the user was created successfully by going to the Your User Pools section of the Cognito console.
  2. Click the user pool you created (for example, Alexa Skill Users).
  3. Select General settings > User and groups.
    • Note: You may notice a Create User option. We don't use the Cognito Console to create users because those users would not have the additional profile fields of address, given_name and family_name.
  4. Select the username with the most recent creation date (it should be the only one if this the first user created in the pool).
  5. Check that this entry has a value for given_name, family_name, email, phone_number, and address.
  6. Click Confirm user to verify the user.
  7. Return to the skill detail page in the Alexa app.
  8. Click Settings and then Link Account to restart the account linking process.
  9. Enter the email and password for the newly verified account.
  10. Your skill and account are now linked. Close the browser tab.

Test It

  1. Go back to the Amazon developer console and click on the Test tab. Test out the skill using utterances such as these:

open link demo

what is my name

what is my number

what’s my address

what is my email

 

Note: You can also test these utterances out using a device associated with your Developer Account or from the ASK CLI using either the ask simulate or ask dialog commands.

 

Summary

Congratulations! You should have successfully created a Cognito User Pool, a skill that uses that pool, a user in that pool, and linked the skill with that account.

This sample can be something you're going to use just for learning, or as the basis for a skill you're building to work with Alexa for Business or for the Alexa Skill Store. Whatever is next, we look forward to seeing what you build!

Resources

Github repository for this tutorial

 

Part 1 - Improve the Customer Experience for your Custom Skills with Personalization