やりたかったこと
lambdaAuthorizerで認証エラーが発生した際に、クライアント側でエラー内容によって処理を分けたい
構成
サーバレスアプリ、SPAの構成
- 静的資源
- Nuxt3(historyモード)
- S3に格納
- API
- nodejs
- lambda-APIGateway
制約事項
Nuxt3のルーティングモードをhistoryモードにしている関係上、CloudFrontにて403エラーを200に変換している。参考
上記の設定を入れている関係上、LambdaAuthorizerで403エラーを返却してもCloudFrontで200に変換されてしまう
LambdaAuthorizerではデフォルト401の場合、エラーメッセージを編集できない
対応したこと
- APIGatewayのGatewayResponseを利用して、403エラーを401に書き換える
- LambdaAuthorizerで403エラーが返却されたときに任意のメッセージを設定する
ソースコード
- APIGatewayのGatewayResponseを利用して、403エラーを401に書き換える
api-stack.ts
import * as apigw from 'aws-cdk-lib/aws-apigateway'
export class ApiStack extends cdk.Stack {
constructor(scope: Construct, id: string, appContext: AppContext, props?: cdk.StackProps) {
super(scope, id, props)
const api = new ApiGateway({
cdkApp: this,
appId: 'testApi'
})
// gatewayResponseを追加
api.apigw.addGatewayResponse('unauthorized', {
type: apigw.ResponseType.ACCESS_DENIED,
statusCode: '401',
})
}
}
- LambdaAuthorizerで403エラーが返却されたときに任意のメッセージを設定する
lambdaAuthorizer.ts
// 抜粋
const generatePolicy = (principal: string, effect: string, resource: string, errorMessage?: string): GeneratePolicy => {
return {
principalId: principal,
policyDocument: {
Version: '2012-10-17',
Statement: [
{
Action: 'execute-api:Invoke',
Effect: effect,
Resource: resource
}
]
},
// contextで任意のエラーメッセージを設定できるようにする
context: {
errorMessage: errorMessage ? errorMessage : 'User is not authorized to access this resource with an explicit deny'
}
}
}
api-stack.ts
api.apigw.addGatewayResponse('unauthorized', {
type: apigw.ResponseType.ACCESS_DENIED,
statusCode: '401',
// lambdaAuthorizerからの返却値のcontextをマッピング
templates: {
'application/json': '{"message": "$context.authorizer.errorMessage"}'
}
})