Ответ 1
Обновление: Я переместил функциональность подписи из приведенного ниже кода кода в aws-cloudfront-sign пакет на NPM, Таким образом, вы можете просто потребовать этот пакет и позвонить getSignedUrl()
.
После некоторого дальнейшего исследования я нашел решение, которое представляет собой комбинацию между этим ответом и методом, который я нашел в Библиотека Boto. Это правда, что подписи S3 URL обрабатываются иначе, чем подписи CloudFront URL. Если вам просто нужно подписать ссылку S3, тогда примерный код в моем первоначальном вопросе будет отлично работать для вас. Тем не менее, это становится немного сложнее, если вы хотите создать подписанные URL-адреса, которые используют ваш дистрибутив CloudFront. Это связано с тем, что подписи CloudFront в настоящее время не поддерживаются в SDK AWS, поэтому вам необходимо создать подпись самостоятельно. В случае, если вам также необходимо это сделать, вот основные шаги. Предположим, у вас уже есть настройка ведра S3:
Настройка CloudFront
- Создайте дистрибутив CloudFront
- Настройте исходный код со следующими настройками
- Начало доменного имени: {your-s3-bucket}
- Ограничить доступ к ведру: Да
- Предоставление разрешений на чтение для ведра: да, обновить ведро.
- Создать пару ключевых слов CloudFront. Должна быть в состоянии сделать это здесь.
Создать подписанный URL-адрес CloudFront
Чтобы отличить подписанный URL CloudFront, вам просто нужно подписать свою политику с помощью RSA-SHA1 и включить его в качестве параметра запроса. Подробнее о пользовательских политиках здесь, но я включил базовый пример в примерный код ниже, который должен вас запустить и запустить. Код примера для Node.js, но процесс может быть применен к любому языку.
var crypto = require('crypto')
, fs = require('fs')
, util = require('util')
, moment = require('moment')
, urlParse = require('url')
, cloudfrontAccessKey = '<your-cloudfront-public-key>'
, expiration = moment().add('seconds', 30) // epoch-expiration-time
// Define your policy.
var policy = {
'Statement': [{
'Resource': 'http://<your-cloudfront-domain-name>/path/to/object',
'Condition': {
'DateLessThan': {'AWS:EpochTime': '<epoch-expiration-time>'},
}
}]
}
// Now that you have your policy defined you can sign it like this:
var sign = crypto.createSign('RSA-SHA1')
, pem = fs.readFileSync('<path-to-cloudfront-private-key>')
, key = pem.toString('ascii')
sign.update(JSON.stringify(policy))
var signature = sign.sign(key, 'base64')
// Finally, you build the URL with all of the required query params:
var url = {
host: '<your-cloudfront-domain-name>',
protocol: 'http',
pathname: '<path-to-s3-object>'
}
var params = {
'Key-Pair-Id=' + cloudfrontAccessKey,
'Expires=' + expiration,
'Signature=' + signature
}
var signedUrl = util.format('%s?%s', urlParse.format(url), params.join('&'))
return signedUrl