【AWS】API Gateway创建Rest API--将文件上传到S3(进阶版)

一、背景

上一篇文章是基础版,这篇文章增加授权方

【AWS】API Gateway创建Rest API--将文件上传到S3(基础版)_某可儿同学的博客的博客-CSDN博客AWS API Gateway创建API将文件上传到S3https://blog.csdn.net/weixin_41758646/article/details/127122227?spm=1001.2014.3001.5501

 二、创建授权方

1、新建Lambda函数,来验证授权方,运行时选择 Node.js 16.x

代码如下:当header中account和password匹配上,则allow,否则deny

exports.handler = function(event, context, callback) {        
    console.log('Received event:', JSON.stringify(event, null, 2));

    // A simple request-based authorizer example to demonstrate how to use request 
    // parameters to allow or deny a request. In this example, a request is  
    // authorized if the client-supplied headerauth1 header, QueryString1
    // query parameter, and stage variable of StageVar1 all match
    // specified values of 'headerValue1', 'queryValue1', and 'stageValue1',
    // respectively.

    // Retrieve request parameters from the Lambda function input:
    var headers = event.headers;
    var queryStringParameters = event.queryStringParameters;
    var pathParameters = event.pathParameters;
    var stageVariables = event.stageVariables;
        
    // Parse the input for the parameter values
    var tmp = event.methodArn.split(':');
    var apiGatewayArnTmp = tmp[5].split('/');
    var awsAccountId = tmp[4];
    var region = tmp[3];
    var restApiId = apiGatewayArnTmp[0];
    var stage = apiGatewayArnTmp[1];
    var method = apiGatewayArnTmp[2];
    var resource = '/'; // root resource
    if (apiGatewayArnTmp[3]) {
        resource += apiGatewayArnTmp[3];
    }
        
    // Perform authorization to return the Allow policy for correct parameters and 
    // the 'Unauthorized' error, otherwise.
    var authResponse = {};
    var condition = {};
    condition.IpAddress = {};
     
    if (headers.account === ""
        && headers.password === "") {
        callback(null, generateAllow('me', event.methodArn));
    }else {
        callback("Unauthorized");
    }
}
     
// Help function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
    // Required output:
    var authResponse = {};
    authResponse.principalId = principalId;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; // default version
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; // default action
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    // Optional output with custom properties of the String, Number or Boolean type.
    authResponse.context = {
        "account": '',
        "password": '',
        "booleanKey": true
    };
    return authResponse;
}
     
var generateAllow = function(principalId, resource) {
    return generatePolicy(principalId, 'Allow', resource);
}
     
var generateDeny = function(principalId, resource) {
    return generatePolicy(principalId, 'Deny', resource);
}

2、创建授权方

授权方名称

类型:选择Lambda

Lambda函数:填写刚创建好的Lambda函数名称

Lambda调用角色:填写调用Lambda函数的角色

Lambda事件负载:选择请求

身份来源:选择标头,添加account和password

授权缓存:取消启用

 三、配置授权方

选择 添加授权方的路径资源方法中的方法请求

授权选择配置好的授权方名称

请求验证程序:无

需要API密钥:否

HTTP请求标头:将account和password配置进来

三、测试API 

 测试通过两种方式:①Postman        ②python代码

获取URL链接

1、Postman

进入Postman,添加PUT请求,复制URL链接,在其后添加上传到S3的路径,在headers中添加account和password,点击send,即可在下方看到请求结果

2、python代码:在headers中添加account和password

import requests


def call_api(_url, _headers, _files):
    res = requests.put(_url, data=_files, headers=_headers)
    return res

def unload_s3(local_file_name,S3_file_name):
    # api gateway call url
    url_ip = ""
    # generate the url
    url = url_ip + S3_file_name

    # the file on your computer
    uploadFile = open(local_file_name, "rb")

    # request headers
    headers = {"account": "",
               "password": ""}

    # call the api2s3 method
    res = call_api(url, headers, uploadFile)
    # print the result
    if res.ok:
        return ("Upload completed successfully!")
    else:
        return ("Upload failed!")

if __name__ == '__main__':

    # local file name 
    local_file_name = ''
    # S3 file_name to upload
    S3_file_name = ''
    unload_s3(local_file_name,S3_file_name)

四、通过CloudFormation创建API

yaml文件如下

AWSTemplateFormatVersion: '2010-09-09'
Description : Template to provision ETL Workflow for api gateway 
Parameters:
  Region:
    Description: 'Specify the Region for resource.'
    Type: String
    Default: ase1
  createDate:
    Type: String
    Default: '2022-07-15'
  Iteration:
    Type: String
    Description: 'Specify the Iteration for Lambda.'
    Default: '001'
  S3Iteration:
    Type: String
    Description: 'Specify the Iteration for S3'
    Default: '001'
  IAMIteration:
    Type: String
    Description: 'Specify the Iteration for IAM roles.'
    Default: '001'

Resources: 
  ApigatewayRestAPI:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: api-uploads3-{Iteration}
      BinaryMediaTypes:
        - "*/*"
      Description: create api to load file to s3
      Mode: overwrite
      EndpointConfiguration:
        Types:
          - REGIONAL
      MinimumCompressionSize: 0
 
  ApigatewayAuthorizer:
    Type: AWS::ApiGateway::Authorizer
    Properties:
      AuthorizerCredentials: "arn:aws:iam::role/iamr-replication-${IAMIteration}"
      AuthorizerResultTtlInSeconds : 0
      AuthorizerUri: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:lamb-apigw-authorizer-${S3Iteration}/invocations"
      Type : REQUEST
      AuthType: custom
      RestApiId: 
        !Ref  ApigatewayRestAPI
      Name: auth-request
      IdentitySource : method.request.header.account,method.request.header.password

  ApigatewayResourceFolder:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: 
        !Ref ApigatewayRestAPI
      PathPart: "{folder}"
      ParentId: !GetAtt 
        - ApigatewayRestAPI
        - RootResourceId

  ApigatewayResourcePartition:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId:
        !Ref ApigatewayRestAPI
      PathPart: "{partition}"
      ParentId:
        !Ref ApigatewayResourceTablename

  ApigatewayResourceTablename:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: 
        !Ref ApigatewayRestAPI
      PathPart: "{tablename}"
      ParentId:
        !Ref ApigatewayResourceFolder     

  ApigatewayResourceFilename:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: 
        !Ref ApigatewayRestAPI
      PathPart: "{filename}"
      ParentId:
        !Ref ApigatewayResourcePartition

  ApigatewayMethodTablename:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizerId:
        !Ref ApigatewayAuthorizer
      AuthorizationType: custom
      RequestParameters: {
        "method.request.path.folder": true,
        "method.request.path.tablename": true,
        "method.request.header.account": true,
        "method.request.header.password": true
      }
      HttpMethod: PUT
      MethodResponses:
        - StatusCode: 200
          ResponseModels: 
            application/json: Empty
      RestApiId:
        !Ref ApigatewayRestAPI
      ResourceId: !GetAtt 
        - ApigatewayResourceTablename
        - ResourceId 
      Integration:
        Type: AWS
        Credentials: "arn:aws:iam::role/iamr-replication-${IAMIteration}"
        IntegrationHttpMethod: PUT
        IntegrationResponses:
          - StatusCode: 200
        PassthroughBehavior: when_no_match
        Uri: "arn:aws:apigateway:${AWS::Region}:s3:path/s3-raw-${Iteration}/{folder}/{tablename}"
        RequestParameters: {
            "integration.request.path.folder" : "method.request.path.folder",
            "integration.request.path.tablename" : "method.request.path.tablename"
          }


  ApigatewayMethodPartition:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizerId:
        !Ref ApigatewayAuthorizer
      AuthorizationType: custom
      RequestParameters: {
        "method.request.path.folder": true,
        "method.request.path.tablename": true,
        "method.request.path.partition": true,
        "method.request.header.account": true,
        "method.request.header.password": true
      }
      HttpMethod: PUT
      MethodResponses:
        - StatusCode: 200
          ResponseModels: 
            application/json: Empty
      RestApiId:
        !Ref ApigatewayRestAPI
      ResourceId: !GetAtt 
        - ApigatewayResourcePartition
        - ResourceId 
      Integration:
        Type: AWS
        Credentials: "arn:aws:iam::role/iamr-replication-${IAMIteration}"
        IntegrationHttpMethod: PUT
        IntegrationResponses:
          - StatusCode: 200
        PassthroughBehavior: when_no_match
        Uri: "arn:aws:apigateway:${AWS::Region}:s3:path/s3-raw-${Iteration}/{folder}/{tablename}/{partition}"
        RequestParameters: {
            "integration.request.path.partition" : "method.request.path.partition",
            "integration.request.path.folder" : "method.request.path.folder",
            "integration.request.path.tablename" : "method.request.path.tablename"
          }


  ApigatewayMethodFilename:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizerId:
        !Ref ApigatewayAuthorizer
      AuthorizationType: custom
      RequestParameters: {
        "method.request.path.folder": true,
        "method.request.path.tablename": true,
        "method.request.path.partition": true,
        "method.request.path.filename": true,
        "method.request.header.account": true,
        "method.request.header.password": true
      }
      HttpMethod: PUT
      MethodResponses:
        - StatusCode: 200
          ResponseModels: 
            application/json: Empty
      RestApiId:
        !Ref ApigatewayRestAPI
      ResourceId: !GetAtt 
        - ApigatewayResourceFilename
        - ResourceId 
      Integration:
        Type: AWS
        Credentials: "arn:aws:iam::role/iamr-replication-${IAMIteration}"
        IntegrationHttpMethod: PUT
        IntegrationResponses:
          - StatusCode: 200
        PassthroughBehavior: when_no_match
        Uri: "arn:aws:apigateway:${AWS::Region}:s3:path/s3-raw-${Iteration}/{folder}/{tablename}/{partition}/{filename}"
        RequestParameters: {
            "integration.request.path.partition" : "method.request.path.partition",
            "integration.request.path.filename" : "method.request.path.filename",
            "integration.request.path.folder" : "method.request.path.folder",
            "integration.request.path.tablename" : "method.request.path.tablename"
          }
          
  ApigatewayDeploymentv3:
    DependsOn: ApigatewayMethodFilename
    Type: AWS::ApiGateway::Deployment
    Properties: 
      RestApiId:
        !Ref ApigatewayRestAPI
      StageName : v3

  PermissionToInvokeLambda: 
    Type: AWS::Lambda::Permission
    Properties: 
      FunctionName: lamb-apigw-authorizer-${Iteration}
      Action: "lambda:InvokeFunction"
      Principal: "apigateway.amazonaws.com"
      SourceArn: !Sub
        - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${APiId}/authorizers/${AuthorizerId}"
        - APiId: 
            !Ref ApigatewayRestAPI
          AuthorizerId: 
            !Ref ApigatewayAuthorizer

Outputs:
  RootResourceId:
    Value: !GetAtt ApigatewayRestAPI.RootResourceId
  AuthorizerId:
    Value: !GetAtt ApigatewayAuthorizer.AuthorizerId

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

某可儿同学的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值