傲渊山岳 发表于 5 天前

aws(学习笔记第四十二课) serverless-backend

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 代码链接

代码毗连(serverless-backend)
1.2 整体架构

https://i-blog.csdnimg.cn/direct/d64bbba7aef34237a977d1e85b0cdeee.png
2 代码分析

2.1 创建S3 bucket

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。
cdk --require-approval never deploy ServerlessBackendStack --parameters uploadBucketName=finlay-20250524-upload
https://i-blog.csdnimg.cn/direct/d50dd91bdb064015a00dcb470e38a309.png
2.2 创建cognito user pool

      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。
https://i-blog.csdnimg.cn/direct/7ba124896146444ebba0e1e1bc4d023a.png
2.3 创建dynamoDB

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。
https://i-blog.csdnimg.cn/direct/cedfb23e9c9041e7afb1acfca9448c67.png
2.4 创建S3 bucket

my_bucket = _s3.Bucket(self, id='s3bucket',
                               bucket_name=bucket_name.value_as_string)
https://i-blog.csdnimg.cn/direct/f4760f96b210463f98cb046d25bf7166.png
使用S3 bucket来进行生存图片,这里S3 bucket的名字是通过cdk deploy执行时候,指定的参数uploadBucketName。
2.5 创建lambda,并赋予权限

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的处理代码。
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函数处理

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
https://i-blog.csdnimg.cn/direct/16ac7f3e83a34a349c72a374de9674df.png
3. 执行cdk

3.1 查抄S3 bucket和dynamoDB

如果同样名字的S3 bucket和dynamoDB已经存在,那么Stack执行会失败,所以提前查抄。


[*]dynamoDBhttps://i-blog.csdnimg.cn/direct/9bda6607021846cbbc565f5b7b3dd605.png
[*]S3 bucket
https://i-blog.csdnimg.cn/direct/b52c3274517d46acb051549c210f056d.png
3.2 开始执行Stack

3.2.1 修改lambda执行环境的代码

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 开始执行

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

https://i-blog.csdnimg.cn/direct/ba5d90c3dcf247928949601f643cf5af.png
到这里,摆设乐成。
4 测试步伐

4.1 Create Cognito User

https://i-blog.csdnimg.cn/direct/ce82e08d83374e90b34119289fe17594.png
之后进入cognito的user配置画面
https://i-blog.csdnimg.cn/direct/ebbadf41600f48d8bd034b199ea37345.png
创建用户,使用user name和password和user pool ID


[*]之后使用aws cli,设定用户和暗码为permanent。这里,用户名字为finlay,暗码自己设定。这里带有XXX都是需要替换的。aws cognito-idp admin-set-user-password --user-pool-id ap-northeast-1-XXXXXX --username finlayXXXX --password XXXXXX --permanent

[*]之后取得finlay这个user的id token
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这里去查找。
https://i-blog.csdnimg.cn/direct/d1af1a211cb945fe89934861ac1ceb0c.png
https://i-blog.csdnimg.cn/direct/441e17d323994b2799f1d2c1907a6967.png
之后生存IdToken随后使用。
4.2 得到API Gateway的调用url

https://i-blog.csdnimg.cn/direct/a765f230095b44ecae8c820f953cf5aa.png
4.3 将图片文件进行base64的encode

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

https://i-blog.csdnimg.cn/direct/db3cf34b6f5c432ab7826e0b55fa5459.png


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

https://i-blog.csdnimg.cn/direct/e3d5562ad7cc4a81997684373542dca8.png
设定形式为
{ "userid": "myUserID", "photo": "image details" }
4.4.3 哀求生存图片

https://i-blog.csdnimg.cn/direct/284a666a220d41e1b300d306d4adf98d.png
方法选择post,之后选择send
最后会显示乐成success。
https://i-blog.csdnimg.cn/direct/c5dd0243b94348a088f5a7fe930b7ae6.png
4.4.4 从S3 bucket中取得生存图片

https://i-blog.csdnimg.cn/direct/17f739a3c9b6465f814e544f06a04c28.png
5 注意扫除Stack



[*]扫除Stack
[*]扫除S3 bucket
[*]扫除dynamoDB

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: aws(学习笔记第四十二课) serverless-backend