Я использую пакет amazon_cognito_identity_dart_2, чтобы сгенерировать и подписать вызов API для Amazon AWS Транскрибировать API в приложении Flutter, но все, казалось бы, правильно отформатированные POST / GET приводят к следующему ответу:
<InvalidSignatureException>
<InvalidSignatureException>
<Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message>
</InvalidSignatureException>
Код, который я использую, приведен ниже, но вот краткое изложение того, что я пробовал / проверял до сих пор:
- Я могу использовать те же учетные данные для успешной загрузки на S3 поэтому я уверен в значениях ключа / секрета
- Генерации новых ключей, обеспечении того, чтобы ключи имели соответствующий доступ к сервису Transcribe, и даже использовании root user accessKeyId / secretAccessKey вместо подхода Cognito (без свойство sessionToken) выдает то же сообщение об ошибке
- Используя тот же пакет, я могу аутентифицироваться с помощью Cognito (как показано ниже), поэтому я уверен в части cognito.dart пакета amazon_cognito_identity_dart_2
- Другие похожие AWS вспомогательные пакеты API (правда, многие из них также полагаться на файл sig_v4.dart), также выдает ту же ошибку
- Пошагово проходит через весь пакет sig_v4.dart, чтобы убедиться, что процесс подписи совпадает с «Простым четырехзадачным 30-шаговым процессом» Amazon! ": https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
- Другие вызовы API Transcribe, кроме Transcribe.StartTranscriptionJob, также не работают
- Различные комбинации, изменения и рекомбинации данных заголовка / запроса / тела don не дает другого результата
- Протестировано как на реальном устройстве iOS, так и на веб-симуляторе в Chrome
import 'package:amazon_cognito_identity_dart_2/cognito.dart';
import 'package:amazon_cognito_identity_dart_2/sig_v4.dart';
_startAWSTranscription() async {
final userPool = CognitoUserPool(
_userPoolId,
_clientId,
);
final cognitoUser = CognitoUser(
_username,
userPool,
);
final authDetails = new AuthenticationDetails(
username: _username,
password: _password,
);
CognitoUserSession session;
try {
session = await cognitoUser.authenticateUser(authDetails);
} catch (e) {
print(e);
}
final credentials = new CognitoCredentials(_identityPoolId, userPool);
try {
await credentials.getAwsCredentials(session.getIdToken().getJwtToken());
} catch (e) {
print(e);
}
final awsSigV4Client = sigV4V2.AwsSigV4Client(
credentials.accessKeyId,
credentials.secretAccessKey,
'https://transcribe.ap-northeast-1.amazonaws.com',
sessionToken: credentials.sessionToken,
region: 'ap-northeast-1',
serviceName: 'transcribe',
defaultContentType: 'application/x-amz-json-1.1',
);
final signedRequest = SigV4Request(
awsSigV4Client,
method: 'POST',
path: '/',
headers: Map<String, String>.from({
'version': '2017-10-26',
'action': 'StartTranscriptionJob',
'x-amz-target': 'Transcribe.StartTranscriptionJob',
}),
queryParams: null,
body: Map<String, dynamic>.from(
{
"TranscriptionJobName": "testapicall",
"LanguageCode": "ja-JP",
"Media": {"MediaFileUri": "s3://$_bucket/$_fileToTranscribe"}
},
),
);
http.Response response;
try {
response = await http.post(
signedRequest.url,
headers: signedRequest.headers,
body: signedRequest.body,
);
} catch (e) {
print(e);
}
print(response.body);
}
По общему признанию, я AWS экосистемы, но требуемые заголовки для AWS Transcribe API плохо документированы. Потребовалось много копаться, чтобы обнаружить, что я изначально пропустил заголовок «x-amz-target»: «Transcribe.StartTranscriptionJob», и было также неоправданно трудно обнаружить тот факт, что тип содержимого по умолчанию должен быть установлен на « применение / х-amz- json -1,1' . Учитывая это, я подозреваю, что мои заголовки не отформатированы должным образом или мне не хватает какого-то ключевого заголовка, но я уже столько раз пробовал, что я не знаю, что происходит.
Мы очень ценим любые идеи или рекомендации, которые вы можете предоставить.