Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (9.79 MB, 388 trang )
Figure 9.1. The overall serverless architecture of the sample authentication service you’re going to implement. HTML and JavaScript
files are hosted on Amazon S3, Lambda functions provide the back end logic, a DynamoDB table is used to store user profiles, and
Amazon SES sends emails for verification and for password resets.
Tip
When implementing your own projects, if you find that you’re creating Lambda functions that
could share code, please consider that you can also have a single function and add an additional
parameter to act on multiple purposes. For example, imagine you have to manipulate a user
with four functions such as createUser, readUser, updateUser, and deleteUser. You can
optionally create a single manageUser function and add an action parameter that can have
different values, such as create, read, update, and delete. The choice depends on your
programming style.
Note
This example uses both client-side (running in the browser) and server-side (running in Lambda
functions) code. Because the code running in the browser is JavaScript, the Lambda function
examples are also provided in JavaScript. The implementation of those functions in Python is
left as an exercise for you to do on your own, because it doesn’t change the architecture or the
logic of the application.
9.1. MANAGING A CENTRALIZED CONFIGURATION
As a developer, it’s a good practice to put configuration information outside your code. In the
application you’re going to build, you’ll use a config.json file to store all deployment-specific
configurations in JSON format (see the following listing).
Listing 9.1. config.json (Template)
Info
To initialize and deploy the sample authentication service, you can use any AWS region where
all the services you need are available. At the time of writing this book, you can choose between
US East (N. Virginia) us-east-1, and EU West (Ireland) eu-west-1. Through some
customizations, you can use a different region for certain services (such as Amazon SES) and
choose among more regions.
Tip
You can optionally use an AWS CLI profile by adding CLI_PROFILE to the config.json file. For
example, add "CLI_PROFILE": "personal" to use your “personal” profile when creating and
deploying the application.
Warning
To protect AWS customers from fraud and abuse, and to help establish trustworthiness for ISPs
and email recipients when sending emails, the first time you use Amazon SES in a region, your
account has sandbox access. With sandbox access, you can send emails only if both the sender
and the destination are verified by Amazon SES, on the specific email address, or as a whole
domain. You can verify a few specific addresses for test and development using the Amazon SES
console at https://console.aws.amazon.com/ses. Remember to verify that you’re using the same
region as the region in the config.json file. You can ask for production access for Amazon SES to
avoid costs. With production access, only the sender address must be verified. Follow the
procedure described at http://docs.aws.amazon.com/ses/latest/DeveloperGuide/requestproduction-access.html.
9.2. AUTOMATING INITIALIZATION AND DEPLOYMENT
The implementation of the sample authentication service requires that multiple AWS resources
be created:
•
•
•
•
•
•
•
6 Lambda functions, to implement the required back end interactions
6 IAM policies, to create an IAM role for each of the Lambda functions
1 DynamoDB table, to store user profiles
1 Cognito identity pool, to federate this authentication service
2 IAM policies, for the authenticated and unauthenticated roles of the Cognito identity
pool
1 S3 bucket to store the client application, built using HTML and JavaScript files
3 IAM trust policies, for the authenticated and unauthenticated roles of the Cognito
identity pool and for the Lambda functions
Creating all those resources from the web console may be a useful exercise, but it can also be
slow and error-prone. To automate all those steps, I created two Bash[1] scripts that you can use:
Bash is the “Bourne Again Shell” incorporating useful features from the Korn shell (ksh) and C shell (csh). For more information on
Bash, see https://www.gnu.org/software/bash/.
1
•
init.sh, to create and initialize all the required resources, so you don’t need to create
•
anything on the web console
deploy.sh, to redeploy and update all back-end and front-end code (Lambda functions
and HTML/JavaScript for the client application)
Note
Before using the scripts, read the next section to understand how to manage the configuration.
Both scripts require the AWS CLI to be installed and configured on the system. To manipulate
JSON content, the scripts use the jq utility, which you can find at https://stedolan.github.io/jq.
The scripts are included in the source code repository for this book. You can use the Bash scripts
natively on Linux or Mac. You can also use a small Linux Amazon EC2 instance, such as
a t2.micro or t2.nano. On Windows platforms, you can run Bash scripts using either of the
following:
•
•
The open source Cygwin project, which includes a large collection of open source tools
that can run on Windows. For more information, see https://www.cygwin.com.
The new native Bash available for Windows 10. For installation and usage,
see https://msdn.microsoft.com/commandline.
Tip
Consider the Bash scripts as an example of how you can use the AWS CLI to automate your
activities on AWS. Any other automation tool that can execute AWS CLI commands or use an
AWS SDK, such as those for Ruby or Python, would work. In your projects, you should use the
tool that you’re most comfortable with.
The config.json file is uploaded with all Lambda functions and is used by
the init.sh and deploy.sh scripts to customize the code in the Lambda functions and in the
IAM roles, and also during certain deployment steps, such as when uploading to Amazon S3.
After you customize the config.json file, you can use the init.sh script to initialize the
application and then deploy.sh to update back end and front end code. You should
run init.shonce, and then you can use deploy.sh to update your environment.
9.3. HAVING SHARED CODE
Every time you create a Lambda function or update its code, you have to upload all of the code
(and binaries) used by the function. But that doesn’t mean that you can’t manage shared code
when developing your application. The “don’t repeat yourself” (DRY) principle applies. You do
need a way to package the code before uploading to AWS Lambda.
In this case, I’m using a lib folder in the root of the project to hold all the shared code.
The init.sh and deploy.sh scripts will automatically include the lib folder with all functions,
together with the configuration file, when building a ZIP file to upload.
For example, in the sample authentication application, we’re using a salting function to encrypt
all passwords stored in the database. To check if a user is providing the correct password—for
example, during login—the same function is used again to compare the results. This function is
required in more than one function and is the perfect candidate for a shared library,
implemented in the cryptoUtils.js file (see the following listing).
Listing 9.2. cryptoUtils.js Shared Library (Node.js)
Tip
In a production environment, the values of byte size, iterations, and the choice of the digest
algorithm should be evaluated with a security expert.
9.4. CREATING THE HOME PAGE
As an entry point for the users, you can create a simple index.html home page with all available
options (figure 9.2).
Figure 9.2. Users start interacting with the application in the home page, which acts as an index for all the available functionalities.
The HTML page in listing 9.3 is a static page, with no JavaScript code.
Listing 9.3. index.html (Home Page)
Note
I use bare HTML in these examples to make it easy to learn. In the source code accompanying
the book, I use Bootstrap to enhance the visual result and make it responsive on mobile
platforms. Bootstrap, originally created by a designer and a developer at Twitter, is a popular
HTML, CSS, and JavaScript framework for developing responsive and mobile-ready web
projects. For more information about Bootstrap, see http://getbootstrap.com.
A sample screenshot of the home page is shown in figure 9.3.
Figure 9.3. The home page for the sample authentication application, with links to the options to sign up a new user, log in, change a
password, or reset a lost password
9.5. SIGNING UP NEW USERS
The first step for the user is to sign up and create a new user (figure 9.4).
Figure 9.4. The Sign Up page is creating a new user on the database and sending a validation email back to the user.
The code for the signUp.html page is shown in the following listing.
Listing 9.4. signUp.html (Sign Up Page)
Tip
You may want to use a more recent version of the AWS JavaScript SDK than the one available at
the time of writing the book. You can find an updated example on how to load the SDK in a
browser at http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-intro.html.
The JavaScript code running in the browser for the signUp.html page is in the signUp.js file (see
the following listing). The IAM role for unauthenticated users of the Cognito identity pool is
shown in listing 9.6.
Listing 9.5. signUp.js (JavaScript in the Browser)
Note
If you use the init.sh and deploy.sh scripts, you don’t need to replace in the source code the
options between angle brackets, such as
previous examples in this book. The init.sh and deploy.sh scripts will automatically replace
those options with the correct ones, based on the current configuration.
Listing 9.6. Policy_Cognito_Unauthenticated_Role
The code for the createUser Lambda function is shown in the following listing, and the IAM role
used by the function is shown in listing 9.8.
Listing 9.7. createUser Lambda Function (Node.js)