web-dev-qa-db-ja.com

API Gatewayカスタム認証からカスタムエラーメッセージをスローする方法

ここ 設計図では、APIゲートウェイは401:未承認で応答します。

私は同じraise Exception('Unauthorized')をラムダに書き込んで、ラムダコンソールからテストすることができました。しかし、ポストマンでは、ステータス500本文付き:

{
  message: null`
} 

「無効な署名」、「TokenExpired」などのカスタムエラーメッセージを追加したいのですが、ドキュメントやガイダンスをいただければ幸いです。

16
imechemi

これは完全に可能ですが、ドキュメントはとても悪くて混乱しています。

方法は次のとおりです。

ゲートウェイ応答テンプレートでアクセスできる$context.authorizerというオブジェクトがあります。詳しくはこちらをご覧ください https://docs.aws.Amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html

これは、承認者ラムダからこのauthorizerオブジェクトに次のように入力する例です。

// A simple TOKEN authorizer example to demonstrate how to use an authorization token 
// to allow or deny a request. In this example, the caller named 'user' is allowed to invoke 
// a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke 
// the request if the token value is 'deny'. If the token value is 'Unauthorized', the function 
// returns the 'Unauthorized' error with an HTTP status code of 401. For any other token value, 
// the authorizer returns an 'Invalid token' error. 

exports.handler =  function(event, context, callback) {
    var token = event.authorizationToken;
    switch (token.toLowerCase()) {
        case 'allow':
            callback(null, generatePolicy('user', 'Allow', event.methodArn));
            break;
        case 'deny':
            
            callback(null, generatePolicy('user', 'Deny', event.methodArn));
            break;
        case 'unauthorized':
            callback("Unauthorized");   // Return a 401 Unauthorized response
            break;
        default:
            callback("Error: Invalid token"); 
    }
};

       var generatePolicy = function(principalId, effect, resource) {
            var authResponse = {};
            
            authResponse.principalId = principalId;
            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 = {
                "stringKey": "stringval custom anything can go here",
                "numberKey": 123,
                "booleanKey": true,
            };
            return authResponse;
        }

ここで重要なのは、この部分を追加することです。

// Optional output with custom properties of the String, Number or Boolean type.

        authResponse.context = {
            "stringKey": "stringval custom anything can go here",
            "numberKey": 123,
            "booleanKey": true,
        };

これは$ context.authorizerで利用可能になります

次に、ゲートウェイの応答タブで次のように本文マッピングテンプレートを設定します。

{"message":"$context.authorizer.stringKey"}

[〜#〜]注[〜#〜]:引用符で囲む必要があります!

最後に、Authorizationトークンを拒否に設定してpostmanでリクエストを送信した後、次のようなペイロードをpostmanから取得します。

{
    "message": "stringval custom anything can go here"
}
15
maxwell

カスタムリソースResponseTemplatesを使用して、@ maxwellソリューションを使用します。拒否応答は、次のように表示されます。

{
  "success":false,
  "message":"Custom Deny Message"
}

これを確認できます https://github.com/SeptiyanAndika/serverless-custom-authorizer

2
Septiyan Andika

500を引き起こしている原因がわからないmessage: nullレスポンス。 Lambda関数の権限の構成が誤っている可能性があります。

Unauthorizedエラーレスポンスをカスタマイズするには、UNAUTHORIZEDエラータイプのゲートウェイレスポンスを設定します。ここで応答ヘッダーとペイロードを設定できます。

0
Jack Kohn - AWS

これは、context.fail()関数を使用して簡単に実現できます。

例:

const customAuthorizer: Handler = (event, context: Context, callback: Callback) => {        
    authenticate(event)
        .then((res) => {
            // result should be as described in AWS docs
            callback(null, res);
        })
        .catch((err) => {
            context.fail("Unauthorized");
        });
}

これにより、次の本文とともに401応答が返されます。

{
    "message": "Unauthorized"
}

これは、エラーをスローすることでも実現できます。

throw new Error('Unauthorized');
0
Lasitha Yapa