У меня есть шлюз API с конечной точкой, которая выполняется интеграцией прокси-сервера AWS Lambda. Я также настроил пользовательский авторизатор для этой конечной точки. Я вижу проблему, из-за которой первый запрос, который я делаю к этой конечной точке, выполняется успешно, но дополнительные вызовы завершаются ошибкой; Я получаю ошибку 403 - Запрещено. Если я подожду некоторое время, я могу сделать еще один запрос, который увенчается успехом, но затем я начинаю видеть ту же проблему.
Вот мой код авторизатора:
const jwt = require('jsonwebtoken');
exports.authorizer = async function (event, context) {
const bearerToken = event.authorizationToken.slice(7);
const { payload } = jwt.decode(bearerToken);
return {
principalId: payload.sub,
policyDocument: {
Version: '2012-10-17',
Statement: [{
Action: 'execute-api:Invoke',
Effect: 'Allow',
Resource: event.methodArn,
}],
},
};
};
В журналах шлюза API для этой конечной точки я вижу, что авторизатор возвращает Allow, но я все еще вижу, что авторизация не удалась:
(50ac5f87-e152-4933-a797-63d84a528f61) The client is not authorized to perform this operation.
Кто-нибудь знает, как и почему это могло произойти?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема, я думаю, в ответе, который отправляет ваш авторизатор. В вашем политическом документе вы можете увидеть, что вы возвращаетесь Resource: event.methodArn.
Обычно это работает, если ваш авторизатор не кэширует ответ от вашего пользовательского авторизатора (это включено по умолчанию). Проблема, с которой вы столкнулись, возникает, когда вы делаете запрос к шлюзу API и получаете ответ из кэша авторизатора, который не соответствует запрошенному ARN текущего запроса. В этом посте объясняется больше о том, как работают авторизаторы Lambda, включая кэширование..
Вы можете убедиться, что это проблема, зайдя в консоль AWS и отключив кеширование для вашего пользовательского авторизатора; как только вы это сделаете, вы больше не должны испытывать эту проблему.
Итак, как вы можете исправить это в долгосрочной перспективе? Есть несколько вариантов:
Отключить кеширование: Это самое простое решение. Недостатком является то, что вы теперь вызываете свой авторизатор с каждым запросом, что увеличивает задержку в вашем API.
Вернуть более широкую политику: Это лучшее решение, но более сложное. Здесь есть несколько вариантов, вы можете вернуть несколько политик Allow в свой ответ авторизатора, которые применяются к любой конечной точке, использующей этот авторизатор.
Если вы посмотрите на формат запроса авторизатора, вы увидите, что methodArn имеет следующий формат:
{
"type":"TOKEN",
"authorizationToken":"{caller-supplied-token}",
"methodArn":"arn:aws:execute-api:{regionId}:{accountId}:{appId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
}
Итак, вы, вероятно, возвращаете что-то вроде этого для methodArn:
arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/my-resource/e56bde3c-7c77-46c6-bdf0-ab4a8cb5f5ca
Более широкая политика, которая будет применяться к любому ресурсу для этой конечной точки, будет следующей:
arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/my-resource/*
Если у вас есть несколько конечных точек, использующих один и тот же авторизатор, вы можете вернуть несколько политик:
{
"principalId": "user",
"policyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/my-resource/*"
},
{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/POST/my-resource"
}
]
}
}