Я не могу получить подписанный URL-адрес, работающий с URL-префиксом для CDN Google Cload.
Я настроил корзину, которая является серверной корзиной для моего экземпляра Cloud CDN. Я успешно настроил ключ подписи URL и создал рабочий подписанный URL для указанного c пути. Все используют инструкцию, найденную в https://cloud.google.com/cdn/docs/using-signed-urls?hl=en_US
Используя мою функцию signCdnUrl2, приведенную ниже. может создать рабочий подписанный URL для указанного ресурса c, например,
https://example.com/foo.mp4?Expires= [EXPIRATION] & KeyName = [KEY_NAME] & Signature = [SIGNATURE]
export function signCdnUrl2(fileName: string, opts: SignedUrlOptions, urlPrefix?: string) {
const expireVal = '' + new Date().getTime() + opts.expires;
const urlToSign = `${opts.baseUrl}/${fileName}?Expires=${expireVal}&KeyName=${opts.keyName}`;
// Compute signature
const keyBuffer = Buffer.from(opts.keyBase64, 'base64');
let signature = createHmac('sha1', keyBuffer).update(urlToSign).digest('base64');
signature = Base64urlUtil.escape(signature);
// Add signature to urlToSign and return signedUrl
return urlToSign + `&Signature=${signature}`;
}
Я хочу избежать «необходимости создавать новую подпись для каждого отдельного URL», поэтому я следую инструкциям на https://cloud.google.com/cdn/docs/using-signed-urls?hl=en_US#url -prefix , чтобы добавить параметр префикса URL.
Я не могу успешно создать рабочий подписанный URL с префиксом. Моя текущая попытка ниже
export function signCdnUrl3(fileName: string, opts: SignedUrlOptions, urlPrefix?: string) {
const expireVal = '' + new Date().getTime() + opts.expires;
const urlPrefixCombined = `${opts.baseUrl}${urlPrefix}`;
// UrlPrefix param if provided otherwise empty string
const urlPrefixEncoded = urlPrefix ? Base64urlUtil.encode(urlPrefixCombined) : '';
// Param string to be signed with key
const paramsToSign = `URLPrefix=${urlPrefixEncoded}&Expires=${expireVal}&KeyName=${opts.keyName}`;
// Compute signature
const keyBuffer = Buffer.from(opts.keyBase64, 'base64');
let signature = createHmac('sha1', keyBuffer).update(paramsToSign).digest('base64');
signature = Base64urlUtil.escape(signature);
// Add signature to url
return `${opts.baseUrl}/${fileName}?${paramsToSign}&Signature=${signature}`;
}
Я получаю ответ 403 из облачного CDN, если я пытаюсь получить доступ к любому ресурсу с данным префиксом в случае root корзины
Запись в журнале от балансировщика нагрузки показывает, что он обнаруживает недействительную подпись
Is что-то неправильно интерпретируется в инструкциях или я что-то пропустил в своей реализации? Будем благодарны за любые рекомендации.
Добавлен код Base64Util для полноты
export class Base64urlUtil {
public static encode(str: string, encoding: any = 'utf8'): string {
const buffer: Buffer = Buffer.from(str, encoding);
const encodedStr: string = buffer.toString('base64');
const final: string = Base64urlUtil.escape(encodedStr);
return final;
}
public static decode(str: string, encoding?: string): string {
return Buffer.from(Base64urlUtil.unescape(str), 'base64').toString(encoding || 'utf8');
}
public static escape(str: string): string {
return str.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
public static unescape(str: string): string {
return (str + '==='.slice((str.length + 3) % 4))
.replace(/-/g, '+')
.replace(/_/g, '/');
}
}
Обновление
Использование реализации, предоставленной @elithrar { ссылка } Я поменял его выборочные значения в SignParams на собственные значения.
let signedParams = signURLPrefix(
"https://<my-server>/sample/360p/",
1588291200,
"<my-key>",
"<valid-key>"
)
Результат был такой:
URLPrefix = aHR0cHM6Ly9zcHluYWwucmNmc29mdHdhcmUuaW8vc2FtcGxlLzM2MHAv & Expires = 1588291200 & KeyName = my-key-name & Signature = wrbOloT + m31ZnQZe * 10 * 64 * 64 * 64 https://my-server/sample/360p/video.mp4?URLPrefix=aHR0cHM6Ly9zcHluYWwucmNmc29mdHdhcmUuaW8vc2FtcGxlLzM2MHAv&Expires=1588291200&KeyName=my-key-name&Signature=wrbOloT+m31ZnQZei2Csqq0XaGY=
Я получаю тот же ответ 403 и соответствующую недействительную подпись в журналах cdn
Попытка использовать два разных ключа подписи, которые отлично работали для подписи одного указанного c URL без префикса url.