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

打印 上一主题 下一主题

主题 2012|帖子 2012|积分 6036

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 整体架构


2 代码分析

2.1 创建S3 bucket

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

2.2 创建cognito user pool

  1.         user_pool = _cognito.UserPool(self, "UserPool")
  2.         user_pool.add_client("app-client", auth_flows=_cognito.AuthFlow(
  3.             user_password=True
  4.         ),
  5.             supported_identity_providers=[
  6.                 _cognito.UserPoolClientIdentityProvider.COGNITO]
  7.         )
  8.         auth = _apigateway.CognitoUserPoolsAuthorizer(self, "imagesAuthorizer",
  9.                                                       cognito_user_pools=[
  10.                                                           user_pool]
  11.                                                       )
复制代码
这里,创建cognito认证方式,创建user pool。并且创建apigateway.CognitoUserPoolsAuthorizer。

2.3 创建dynamoDB

  1. my_table = _dynamodb.Table(self, id='dynamoTable', table_name='formmetadata', partition_key=_dynamodb.Attribute(
  2.             name='userid', type=_dynamodb.AttributeType.STRING)) #change primary key here
复制代码
创建dynamoDB,用来存储image文件的metadata。

2.4 创建S3 bucket

  1. my_bucket = _s3.Bucket(self, id='s3bucket',
  2.                                bucket_name=bucket_name.value_as_string)
复制代码

使用S3 bucket来进行生存图片,这里S3 bucket的名字是通过cdk deploy执行时候,指定的参数uploadBucketName。
2.5 创建lambda,并赋予权限

  1. my_lambda = _lambda.Function(self, id='lambdafunction', function_name="formlambda", runtime=_lambda.Runtime.PYTHON_3_9,
  2.                                      handler='index.handler',
  3.                                      code=_lambda.Code.from_asset(
  4.                                          os.path.join("./", "lambda-handler")),
  5.                                      environment={
  6.                                          'bucket': my_bucket.bucket_name,
  7.                                          'table': my_table.table_name
  8.                                      }
  9.                                      )
  10. my_bucket.grant_read_write(my_lambda)
  11. 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的处理代码。
  1. def upload_metadata(key, userid):
  2.     table = os.environ['table']
  3.     bucket = os.environ['bucket']
  4.     reference = {'Bucket': {'S': bucket}, 'Key': {'S': key}}
  5.     response = dynamodb.put_item(
  6.         TableName=table,
  7.         Item={"userid": {
  8.             'S': userid}, "photo_reference": {'M': reference}})
  9.     print(response)
  10. def upload_image(image_id, img, userid):
  11.     bucket = os.environ['bucket']
  12.     extension = imghdr.what(None, h=img)
  13.     key = f"{image_id}.{extension}"
  14.     try:
  15.         s3.put_object(Bucket=bucket, Key=key, Body=img)
  16.         upload_metadata(key, userid)
  17.     except botocore.exceptions.ClientError as e:
  18.         print(e)
  19.         return False
  20.     return True
  21. def handler(event, context):
  22.     print(event)
  23.     # Generate random image id
  24.     image_id = str(uuid.uuid4())
  25.     data = json.loads(event['body'])
  26.     userid = data['userid']
  27.     img = base64.b64decode(data['photo'])
  28.     if upload_image(image_id, img, userid):
  29.         return {
  30.             'statusCode': 200,
  31.             'headers': {
  32.                 'Access-Control-Allow-Headers': '*',
  33.                 'Access-Control-Allow-Origin': '*',
  34.                 'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
  35.             },
  36.             'body': json.dumps('Success!')
  37.         }
  38.     return {
  39.         'statusCode': 500,
  40.         'headers': {
  41.             'Access-Control-Allow-Headers': '*',
  42.             'Access-Control-Allow-Origin': '*',
  43.             'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
  44.         },
  45.         'body': json.dumps('Request Failed!')
  46.     }
复制代码
2.6 创建API Gateway,并指定为lambda函数处理

  1. my_api = _apigateway.LambdaRestApi(
  2.             self, id='lambdaapi', rest_api_name='formapi', handler=my_lambda, proxy=True)
  3.         postData = my_api.root.add_resource("form")
  4.         postData.add_method("POST", authorizer=auth,
  5.                           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执行环境的代码

  1. my_lambda = _lambda.Function(self, id='lambdafunction', function_name="formlambda", runtime=_lambda.Runtime.PYTHON_3_9,
  2.                                      handler='index.handler',
  3.                                      code=_lambda.Code.from_asset(
  4.                                          os.path.join("./", "lambda-handler")),
  5.                                      environment={
  6.                                          'bucket': my_bucket.bucket_name,
  7.                                          'table': my_table.table_name
  8.                                      }
  9.                                      )
复制代码
如果太旧的python执行环境,会导致摆设失败,这里指定_lambda.Runtime.PYTHON_3_9。
3.2.2 开始执行

  1. cd serverless-backend
  2. python -m venv .venv
  3. source .venv/Script/activate
  4. pip install -r requirement.txt
  5. 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都是需要替换的。
    1. aws cognito-idp admin-set-user-password --user-pool-id ap-northeast-1-XXXXXX --username finlayXXXX --password XXXXXX --permanent
    复制代码
  • 之后取得finlay这个user的id token
  1. 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

  1. import base64
  2. with open(r"d:\test.jpg", "rb") as image_file:
  3.     base64_string = base64.b64encode(image_file.read()).decode('utf-8')
  4. 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


设定形式为
  1. { "userid": "myUserID", "photo": "image details" }
复制代码
4.4.3 哀求生存图片


方法选择post,之后选择send
最后会显示乐成success。

4.4.4 从S3 bucket中取得生存图片


5 注意扫除Stack



  • 扫除Stack
  • 扫除S3 bucket
  • 扫除dynamoDB

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

傲渊山岳

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表