文章目录
- [aws(学习笔记第四十二课) serverless-backend](#aws(学习笔记第四十二课) serverless-backend)
- 学习内容:
-
- [1. 整体架构](#1. 整体架构)
-
- [1.1 代码链接](#1.1 代码链接)
- [1.2 整体架构](#1.2 整体架构)
- [2 代码分析](#2 代码分析)
-
- [2.1 创建`S3 bucket`](#2.1 创建
S3 bucket
) - [2.2 创建`cognito user pool`](#2.2 创建
cognito user pool
) - [2.3 创建`dynamoDB`](#2.3 创建
dynamoDB
) - [2.4 创建`S3 bucket`](#2.4 创建
S3 bucket
) - [2.5 创建`lambda`,并赋予权限](#2.5 创建
lambda
,并赋予权限) - [2.6 创建`API Gateway`,并指定为`lambda`函数处理](#2.6 创建
API Gateway
,并指定为lambda
函数处理)
- [2.1 创建`S3 bucket`](#2.1 创建
- [3. 执行`cdk`](#3. 执行
cdk
) -
- [3.1 检查`S3 bucket`和`dynamoDB`](#3.1 检查
S3 bucket
和dynamoDB
) - [3.2 开始执行`Stack`](#3.2 开始执行
Stack
) -
- [3.2.1 修改`lambda`执行环境的代码](#3.2.1 修改
lambda
执行环境的代码) - [3.2.2 开始执行](#3.2.2 开始执行)
- [3.2.1 修改`lambda`执行环境的代码](#3.2.1 修改
- [3.1 检查`S3 bucket`和`dynamoDB`](#3.1 检查
- [4 测试程序](#4 测试程序)
-
- [4.1 `Create Cognito User`](#4.1
Create Cognito User
) - [4.2 获得`API Gateway`的调用`url`](#4.2 获得
API Gateway
的调用url
) - [4.3 将图片文件进行`base64`的`encode`](#4.3 将图片文件进行
base64
的encode
) - [4.4 使用`Postman`进行`post`](#4.4 使用
Postman
进行post
) -
- [4.4.1 设定认证情报`Authorization`](#4.4.1 设定认证情报
Authorization
) - [4.4.2 设定`json`](#4.4.2 设定
json
) - [4.4.3 请求保存图片](#4.4.3 请求保存图片)
- [4.4.4 从`S3 bucket`中取得保存图片](#4.4.4 从
S3 bucket
中取得保存图片)
- [4.4.1 设定认证情报`Authorization`](#4.4.1 设定认证情报
- [4.1 `Create Cognito User`](#4.1
- [5 注意清除`Stack`](#5 注意清除
Stack
)
aws(学习笔记第四十二课) serverless-backend
- 使用
Amazon API Gateway
以及lamda
进行后台处理
学习内容:
- 使用
Amazon API Gateway
- 使用
lambda
处理API Gateway
请求,接受json
参数 - 使用
Amazon S3 - Bucket to store images or files
- 使用
Amazon DynamoDB
- 使用
Amazon Cognito
进行用户认证
1. 整体架构
1.1 代码链接
1.2 整体架构

2 代码分析
2.1 创建S3 bucket
python
bucket_name = _cfnParameter(self, "uploadBucketName", type="String",
description="The name of the Amazon S3 bucket where uploaded images will be stored.")
my_bucket = _s3.Bucket(self, id='s3bucket',
bucket_name=bucket_name.value_as_string)
my_bucket.grant_read_write(my_lambda)
这里,S3 bucket
的名字是通过cdk deploy
时候,指定的参数uploadBucketName
。
shell
cdk --require-approval never deploy ServerlessBackendStack --parameters uploadBucketName=finlay-20250524-upload

2.2 创建cognito user pool
python
user_pool = _cognito.UserPool(self, "UserPool")
user_pool.add_client("app-client", auth_flows=_cognito.AuthFlow(
user_password=True
),
supported_identity_providers=[
_cognito.UserPoolClientIdentityProvider.COGNITO]
)
auth = _apigateway.CognitoUserPoolsAuthorizer(self, "imagesAuthorizer",
cognito_user_pools=[
user_pool]
)
这里,创建cognito
认证方式,创建user pool
。并且创建apigateway.CognitoUserPoolsAuthorizer
。
2.3 创建dynamoDB
python
my_table = _dynamodb.Table(self, id='dynamoTable', table_name='formmetadata', partition_key=_dynamodb.Attribute(
name='userid', type=_dynamodb.AttributeType.STRING)) #change primary key here
创建dynamoDB
,用来存储image
文件的metadata
。

2.4 创建S3 bucket
python
my_bucket = _s3.Bucket(self, id='s3bucket',
bucket_name=bucket_name.value_as_string)

使用S3 bucket
来进行保存图片,这里S3 bucket
的名字是通过cdk deploy
执行时候,指定的参数uploadBucketName
。
2.5 创建lambda
,并赋予权限
python
my_lambda = _lambda.Function(self, id='lambdafunction', function_name="formlambda", runtime=_lambda.Runtime.PYTHON_3_9,
handler='index.handler',
code=_lambda.Code.from_asset(
os.path.join("./", "lambda-handler")),
environment={
'bucket': my_bucket.bucket_name,
'table': my_table.table_name
}
)
my_bucket.grant_read_write(my_lambda)
my_table.grant_read_write_data(my_lambda)
这里的lambda
函数用来接收API Gateway
来的请求处理,并且dynamoDB
的table
和S3 bucket
都对lambda
函数打开了read/write
权限。
- 保存
image
文件的meta data
- 保存
image
文件到S3 bucket
下面是lambda
的处理代码。
python
def upload_metadata(key, userid):
table = os.environ['table']
bucket = os.environ['bucket']
reference = {'Bucket': {'S': bucket}, 'Key': {'S': key}}
response = dynamodb.put_item(
TableName=table,
Item={"userid": {
'S': userid}, "photo_reference": {'M': reference}})
print(response)
def upload_image(image_id, img, userid):
bucket = os.environ['bucket']
extension = imghdr.what(None, h=img)
key = f"{image_id}.{extension}"
try:
s3.put_object(Bucket=bucket, Key=key, Body=img)
upload_metadata(key, userid)
except botocore.exceptions.ClientError as e:
print(e)
return False
return True
def handler(event, context):
print(event)
# Generate random image id
image_id = str(uuid.uuid4())
data = json.loads(event['body'])
userid = data['userid']
img = base64.b64decode(data['photo'])
if upload_image(image_id, img, userid):
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
'body': json.dumps('Success!')
}
return {
'statusCode': 500,
'headers': {
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
'body': json.dumps('Request Failed!')
}
2.6 创建API Gateway
,并指定为lambda
函数处理
python
my_api = _apigateway.LambdaRestApi(
self, id='lambdaapi', rest_api_name='formapi', handler=my_lambda, proxy=True)
postData = my_api.root.add_resource("form")
postData.add_method("POST", authorizer=auth,
authorization_type=_apigateway.AuthorizationType.COGNITO) # POST images/files & metadata
这里,
- 指定
lambda
函数作为处理http post
请求的handler
- 指定认证方式为
cognito
的user pool
3. 执行cdk
3.1 检查S3 bucket
和dynamoDB
如果同样名字的S3 bucket
和dynamoDB
已经存在,那么Stack
执行会失败,所以提前检查。
dynamoDB
S3 bucket
3.2 开始执行Stack
3.2.1 修改lambda
执行环境的代码
python
my_lambda = _lambda.Function(self, id='lambdafunction', function_name="formlambda", runtime=_lambda.Runtime.PYTHON_3_9,
handler='index.handler',
code=_lambda.Code.from_asset(
os.path.join("./", "lambda-handler")),
environment={
'bucket': my_bucket.bucket_name,
'table': my_table.table_name
}
)
如果太旧的python
执行环境,会导致部署失败,这里指定_lambda.Runtime.PYTHON_3_9
。
3.2.2 开始执行
shell
cd serverless-backend
python -m venv .venv
source .venv/Script/activate
pip install -r requirement.txt
cdk --require-approval never deploy ServerlessBackendStack --parameters uploadBucketName=finlay-20250524-upload

到这里,部署成功。
4 测试程序
4.1 Create Cognito User

之后进入cognito
的user
配置画面
创建用户,使用user name
和password
和user pool ID
-
之后使用
aws cli
,设定用户和密码为permanent
。这里,用户名字为finlay
,密码自己设定。这里带有XXX
都是需要替换的。shellaws cognito-idp admin-set-user-password --user-pool-id ap-northeast-1-XXXXXX --username finlayXXXX --password XXXXXX --permanent
-
之后取得
finlay
这个user的id token
shell
aws cognito-idp initiate-auth --region ap-northeast-1 --auth-flow USER_PASSWORD_AUTH --client-id XXXXXX --auth-parameters USERNAME=finlay,PASSWORD=XXXXXX
这里的--client-id
必须要去cloudformation
这里去查找。
之后保存IdToken
随后使用。
4.2 获得API Gateway
的调用url

4.3 将图片文件进行base64
的encode
python
import base64
with open(r"d:\test.jpg", "rb") as image_file:
base64_string = base64.b64encode(image_file.read()).decode('utf-8')
print(base64_string)
注意python
文件不能为base64
,取其他名字即可。
4.4 使用Postman
进行post
4.4.1 设定认证情报Authorization

URL
设定
URL
这里设定成前面取得的API Gateway
的url
,注意,后缀加上form
。
https://XXXXXX.execute-api.ap-northeast-1.amazonaws.com/prod/form
Authentication
设定
这里设定成前面取得的idToken
。
4.4.2 设定json

设定形式为
json
{ "userid": "myUserID", "photo": "image details" }
4.4.3 请求保存图片

方法选择post
,之后选择send
最后会显示成功success
。
4.4.4 从S3 bucket
中取得保存图片

5 注意清除Stack
- 清除
Stack
- 清除
S3 bucket
- 清除
dynamoDB