Sau khi tạo User pool, chúng ta tạo một API và một hàm Lambda để xử lý các yêu cầu đăng ký và đăng nhập người dùng.
Thêm các tham số cần thiết cho hàm để được thực thi.
Sao chép các khối mã dưới đây vào tệp template.yaml trong nguồn của tệp fcj-book-shop-sam-ws3.zip đã tải xuống trong phần chuẩn bị.
cognitoClientID:
Type: String
Default: APP_CLIENT_ID
cognitoClientSecret:
Type: String
Default: APP_CLIENT_SECRET
Thay đổi APP_CLIENT_ID và APP_CLIENT_SECRET thành giá trị đã ghi lại của ứng dụng Cognito trước đó.
Tạo một triển khai sam
mới.
Mở tệp template.yaml trong nguồn của tệp fcj-book-shop-sam-ws3.zip đã tải xuống trong phần chuẩn bị.
Chú thích các khối mã như dưới đây.
Chạy các lệnh dưới đây.
sam build
sam validate
sam deploy
Tại tệp template.yaml trong nguồn của tệp fcj-book-shop-sam-ws3.zip đã tải xuống trong phần chuẩn bị.
Tạo tham số Registration.
Sao chép và dán khối mã dưới đây như hình ảnh dưới đây.
registerPathPart:
Type: String
Default: register
Tạo hàm Registration.
Sao chép và dán các khối mã dưới đây vào cuối tệp.
Register:
Type: AWS::Serverless::Function
Properties:
CodeUri: fcj-book-shop/register
Handler: register.lambda_handler
Runtime: python3.11
FunctionName: register
Architectures:
- x86_64
Environment:
Variables:
CLIENT_ID: !Ref cognitoClientID
CLIENT_SECRET: !Ref cognitoClientSecret
RegisterApiResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref BookApi
ParentId: !GetAtt BookApi.RootResourceId
PathPart: !Ref registerPathPart
RegisterApiOptions:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: OPTIONS
RestApiId: !Ref BookApi
ResourceId: !Ref RegisterApiResource
AuthorizationType: NONE
Integration:
Type: MOCK
IntegrationResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: "'*'"
method.response.header.Access-Control-Allow-Methods: "'OPTIONS,POST,GET,DELETE'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
MethodResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Headers: true
RegisterApi:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: POST
RestApiId: !Ref BookApi
ResourceId: !Ref RegisterApiResource
AuthorizationType: NONE
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # For Lambda integrations, you must set the integration method to POST
Uri: !Sub >-
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Register.Arn}/invocations
MethodResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Headers: true
RegisterApiInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref Register
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
SourceAccount: !Ref "AWS::AccountId"
Cấu trúc thư mục như dưới đây.
fcj-book-shop-sam-ws3
├── fcj-book-shop
│ ├── register
│ │ └── register.py
│ ├── ...
│
└── template.yaml
Tạo thư mục register trong thư mục fcj-book-shop-sam-ws3/fcj-book-shop/.
Tạo tệp register.py và sao chép mã sau vào đó.
import json
import boto3
import os
import hmac
import hashlib
import base64
# Initialize the Cognito client
client = boto3.client("cognito-idp")
headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET,DELETE",
"Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token"
}
def lambda_handler(event, context):
# Get the body from the event and parse it as JSON
body = json.loads(event["body"])
# Get the username and password from the body
username = body["username"]
password = body["password"]
# Get Client ID and Client Secret from environment variables
client_id = os.environ["CLIENT_ID"]
client_secret = os.environ["CLIENT_SECRET"]
# Generate the secret hash
message = bytes(username + client_id, 'utf-8')
key = bytes(client_secret, 'utf-8')
secret_hash = base64.b64encode(
hmac.new(key, message, digestmod=hashlib.sha256).digest()).decode()
try:
# Sign up the user
client.sign_up(
ClientId=client_id,
SecretHash=secret_hash,
Username=username,
Password=password
)
return {
"statusCode": 200,
"headers": headers,
"body": json.dumps("User registration successful")
}
except Exception as e:
print(f"Error registering user: {e}")
raise Exception(f"Error registering user: {e}")
Tại tệp template.yaml trong nguồn của tệp fcj-book-shop-sam-ws3.zip đã tải xuống trong phần chuẩn bị.
Tạo tham số Confirm.
Sao chép và dán khối mã dưới đây như hình ảnh dưới đây.
confirmPathPart:
Type: String
Default: confirm_user
Tạo hàm Confirm.
Sao chép và dán các khối mã dưới đây vào cuối tệp.
Confirm:
Type: AWS::Serverless::Function
Properties:
CodeUri: fcj-book-shop/confirm_user
Handler: confirm_user.lambda_handler
Runtime: python3.11
FunctionName: confirm
Architectures:
- x86_64
Environment:
Variables:
CLIENT_ID: !Ref cognitoClientID
CLIENT_SECRET: !Ref cognitoClientSecret
ConfirmApiResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref BookApi
ParentId: !GetAtt BookApi.RootResourceId
PathPart: !Ref confirmPathPart
ConfirmApiOptions:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: OPTIONS
RestApiId: !Ref BookApi
ResourceId: !Ref ConfirmApiResource
AuthorizationType: NONE
Integration:
Type: MOCK
IntegrationResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: "'*'"
method.response.header.Access-Control-Allow-Methods: "'OPTIONS,POST,GET,DELETE'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
MethodResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Headers: true
ConfirmApi:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: POST
RestApiId: !Ref BookApi
ResourceId: !Ref ConfirmApiResource
AuthorizationType: NONE
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # For Lambda integrations, you must set the integration method to POST
Uri: !Sub >-
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Confirm.Arn}/invocations
MethodResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Headers: true
ConfirmApiInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref Confirm
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
SourceAccount: !Ref "AWS::AccountId"
Cấu trúc thư mục như dưới đây.
fcj-book-shop-sam-ws3
├── fcj-book-shop
│ ├── register
│ │ └── register.py
│ ├── confirm_user
│ │ └── confirm_user.py
│ ├── ...
│
└── template.yaml
Tạo thư mục confirm_user trong thư mục fcj-book-shop-sam-ws3/fcj-book-shop/.
Tạo tệp confirm_user.py và sao chép mã sau vào đó.
import json
import boto3
import os
import hmac
import hashlib
import base64
# Initialize the Cognito client
client = boto3.client("cognito-idp")
headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET,DELETE",
"Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token"
}
def lambda_handler(event, context):
# Get the body from the event and parse it as JSON
body = json.loads(event["body"])
# Extract the necessary information from the event
username = body["username"]
confirmation_code = body["confirmation_code"]
# Get Client ID and Client Secret from environment variables
client_id = os.environ["CLIENT_ID"]
client_secret = os.environ["CLIENT_SECRET"]
# Generate the secret hash
message = bytes(username + client_id, "utf-8")
key = bytes(client_secret, "utf-8")
secret_hash = base64.b64encode(
hmac.new(key, message, digestmod=hashlib.sha256).digest()).decode()
try:
# Confirm the user
response = client.confirm_sign_up(
ClientId=client_id,
SecretHash=secret_hash,
Username=username,
ConfirmationCode=confirmation_code
)
return {
"statusCode": 200,
"headers": headers,
"body": json.dumps("User confirmed successfully")
}
except Exception as e:
print(f"Error confirming user: {e}")
raise Exception(f"Error confirming user: {e}")
Tại tệp template.yaml trong nguồn của tệp fcj-book-shop-sam-ws3.zip đã tải xuống trong phần chuẩn bị.
Tạo tham số Login.
Sao chép và dán khối mã dưới đây như hình ảnh dưới đây.
loginPathPart:
Type: String
Default: login
Tạo hàm Login.
Sao chép và dán các khối mã dưới đây vào cuối tệp.
Login:
Type: AWS::Serverless::Function
Properties:
CodeUri: fcj-book-shop/login
Handler: login.lambda_handler
Runtime: python3.11
FunctionName: login
Architectures:
- x86_64
Environment:
Variables:
CLIENT_ID: !Ref cognitoClientID
CLIENT_SECRET: !Ref cognitoClientSecret
LoginApiResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref BookApi
ParentId: !GetAtt BookApi.RootResourceId
PathPart: !Ref loginPathPart
LoginApiOptions:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: OPTIONS
RestApiId: !Ref BookApi
ResourceId: !Ref LoginApiResource
AuthorizationType: NONE
Integration:
Type: MOCK
IntegrationResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: "'*'"
method.response.header.Access-Control-Allow-Methods: "'OPTIONS,POST,GET,DELETE'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
MethodResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Headers: true
LoginApi:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: POST
RestApiId: !Ref BookApi
ResourceId: !Ref LoginApiResource
AuthorizationType: NONE
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # For Lambda integrations, you must set the integration method to POST
Uri: !Sub >-
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Login.Arn}/invocations
MethodResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Headers: true
LoginApiInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref Login
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
SourceAccount: !Ref "AWS::AccountId"
Cấu trúc thư mục như dưới đây.
fcj-book-shop-sam-ws3
├── fcj-book-shop
│ ├── register
│ │ └── register.py
│ ├── confirm_user
│ │ └── confirm_user.py
│ ├── login
│ │ └── login.py
│ ├── ...
│
└── template.yaml
Tạo thư mục login trong thư mục fcj-book-shop-sam-ws3/fcj-book-shop/.
Tạo tệp login.py và sao chép mã sau vào đó.
import json
import boto3
import os
import hmac
import hashlib
import base64
client = boto3.client("cognito-idp")
headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET,DELETE",
"Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token"
}
def lambda_handler(event, context):
# Get the body from the event and parse it as JSON
body = json.loads(event["body"])
# Get the username and password from the body
username = body["username"]
password = body["password"]
# Get Client ID and Client Secret from environment variables
client_id = os.environ["CLIENT_ID"]
client_secret = os.environ["CLIENT_SECRET"]
# Generate the secret hash
message = bytes(username + client_id, 'utf-8')
key = bytes(client_secret, 'utf-8')
secret_hash = base64.b64encode(
hmac.new(key, message, digestmod=hashlib.sha256).digest()).decode()
try:
response = client.initiate_auth(
AuthFlow="USER_PASSWORD_AUTH",
AuthParameters={
"USERNAME": username,
"PASSWORD": password,
"SECRET_HASH": secret_hash
},
ClientId=client_id,
)
return {
"statusCode": 200,
"headers": headers,
"body": json.dumps({
"message": "Login successful",
"id_token": response["AuthenticationResult"]["IdToken"],
"access_token": response["AuthenticationResult"]["AccessToken"],
"refresh_token": response["AuthenticationResult"]["RefreshToken"]
})
}
except Exception as e:
print(f"Error login: {e}")
raise Exception(f"Error login: {e}")
Bỏ chú thích và chỉnh sửa khối mã này.
BookApiDeployment:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId: !Ref BookApi
DependsOn:
- BookApiGet
- BookApiCreate
- BookApiDelete
- RegisterApi
- ConfirmApi
- LoginApi
BookApiStage:
Type: AWS::ApiGateway::Stage
Properties:
RestApiId: !Ref BookApi
StageName: !Ref stage
DeploymentId: !Ref BookApiDeployment
Chạy các lệnh dưới đây. Để mặc định.
sam build
sam validate
sam deploy
Chúng ta đã hoàn thành việc triển khai các API và hàm Lambda.