API Gateway的简介

Amazon API Gateway 是一种完全托管的服务,可以帮助开发者轻松创建、发布、维护、监控和保护任意规模的 API。API Gateway 负责管理所有任务,涉及接受和处理成千上万个并发 API 调用,包括流量管理、授权和访问控制、监控以及 API 版本管理。API Gateway 没有最低费用或启动成本。您只需为您收到的 API 调用和传出的数据量付费,使用 API Gateway 分级定价模式,随着 API 使用规模的增加,您可以减少花费。

API Gateway的方法请求和集成请求映射

https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/request-response-data-mappings.html

1)默认映射方式,URL POST方法 request body可以默认传到lambda的event,可以看到方法请求体中的两个参数被传递到了lambda中作为参数

2)Get 方法传递Url Parma传递映射,通过设置方法请求和集成请求,将Url Parma作为lambda的参数,其中用到了Velocity 模板语言 (VTL) 

方法请求中设置URL查询字符串参数

集成请求中设置URL查询字符串参数,映射模板参数配置

可以看到通过URL的参数groupName值'aaa'已经可以传到lambda的参数中了

3)Url header的信息映射,通过集成请求传递作为请求体传到lambda的参数中

https://amazonaws-china.com/cn/premiumsupport/knowledge-center/custom-headers-api-gateway-lambda/?nc1=h_ls

集成请求中配置映射模板取得url header中的各个键值对

可以看到,LAMBDA已经获取了Url header的authorization的JWT token

代码中可以使用这个JWT token进行相应的业务逻辑的处理,判断token的合法性和过期,还有相应的权限,等等..

4)Url path parma的映射,通过设置方法请求和集成请求,将Url param作为lambda的参数

集成请求中配置映射模板取得url参数id的值

可以看到url中的id值1,已经可以在lambda中取到了

API Gateway的方法响应和集成响应映射

有时候需要在项目中的API Gateway自定义一些header的信息返回,可以在集成响应和方法响应中定义一些header的键值对

在集成响应中定义值

重新部署API GW,打开网站,查看对应的API GW,可以看到自定义的header已经成功加上去了

创建API GW的授权方

可以自定义API GW的授权,对于API GW进行安全限制

创建新的lambda , 自定义授权机制,判断token的合法性和过期,还有相应的权限,等等..,注意返回格式一定要符合IAM policy的要求

exports.handler =  function(event, context, callback) {
    var token = event.authorizationToken;
    var tokenInvalidReason;
    if (token == null || token == undefined || token == ''){
            callback("Unauthorized");
    }
    else{
        var token = event.authorizationToken;
        if( token.indexOf("Bearer ") > -1){
            token = token.substring(7);
            var array = token.split('.');
            console.log("array length",array.length);
            if(array.length > 2){
                token = array[1];
            }
            console.log('token is: ' + token);
        }
        const hash = new Buffer(token, 'base64').toString();
        console.log('analysis base auth hash is: ' + hash);
        var authObj = JSON.parse(hash);

        if (!authObj.scope){
            callback("Unauthorized");
        }
        if(authObj.scope.indexOf('read_snfa_air') != -1) {
             callback(null, generatePolicy('user', 'Allow',event.methodArn,"xxx.xx.x"));
        }
        if (authObj.scope.indexOf('read_xxxx_profile') == -1){
            callback("Unauthorized");
        }
        var now = parseInt(Date.now() / 1000);
        console.log("Expired time in token",authObj.exp);
        console.log("Current time",now);

        if (authObj.exp < now) {
            console.log("Token Expired");
            callback("Token Expired");
        }
        var eid = authObj.samaccount_name;
        //event.eid = eid;
        //console.log(generatePolicy('user', 'Allow',event.methodArn));
        callback(null, generatePolicy('user', 'Allow',event.methodArn,eid));
    }
  
};

// Help function to generate an IAM policy
var generatePolicy = function(principalId, effect,resource,eid) {
    var authResponse = {};
    //authResponse.eid = "steven.rui.zhang";
    authResponse.principalId = principalId;
    //authResponse.eid = eid;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; 
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; 
        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 = {
        'eid' : eid
    };
    return authResponse;
}

在API GW中新建授权方,绑定上述的lambda

对于需要使用授权的API GW 方法请求中配置授权

处理 API Gateway 中的 Lambda 错误

https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html

对于 Lambda 自定义集成,您必须将在集成响应中由 Lambda 返回的错误映射到客户端的标准 HTTP 错误响应。否则,Lambda 错误会默认返回为 200 OK 响应,并且结果对于您的 API 用户而言并不直观。

在方法响应中定义HTTP状态,然后再集成响应中定义Lambda错误正则表达式

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐