Введение
В современных приложениях, особенно работающих с мультимедийным контентом, эффективное управление такими ресурсами, как изображения, имеет решающее значение для плавного пользовательского опыта. Amazon Simple Storage Service (S3) является популярным выбором.
Один из распространенных подходов к обеспечению безопасного доступа к ресурсам — использование предварительно подписанных URL-адресов. Эти URL-адреса предоставляют временный доступ к определенным ресурсам в корзине S3, позволяя контролировать доступ без ущерба для безопасности.
Хотя обычно предварительно подписанные URL-адреса генерируются на серверной стороне и предоставляются на фронтенд, бывают ситуации, когда необходимо обрабатывать предварительно подписанные URL-адреса непосредственно на фронтенде приложения React Native. Это может быть связано с различными причинами, такими как динамический контент, управление доступом для конкретных пользователей или необходимость тонкого управления доступом.
В этом руководстве мы шаг за шагом рассмотрим процесс предварительной подписи URL-адресов AWS S3 в приложении React Native.
Хотя документация AWS предоставляет исчерпывающие инструкции по предварительно подписанным URL-адресам, она может не предлагать конкретных инструкций по интеграции этой функциональности в приложение React Native. Документация AWS по предварительно подписанным URL-адресам
Давайте углубимся в то, как это сделать в нашем приложении React Native.
Предварительные условия
Вам нужна учетная запись AWS для доступа к сервисам Amazon S3. Если у вас ее нет, вы можете зарегистрироваться здесь.
Необходимы Ключи доступа и секретные ключи для аутентификации запросов к сервисам AWS, включая S3. Вы можете получить эти учетные данные, создав пользователя IAM с соответствующими разрешениями в консоли управления AWS. Убедитесь, что вы храните эти учетные данные безопасно и избегайте их раскрытия в общедоступных репозиториях или клиентском коде.
Необходим Node.js для установки пакетов и запуска инструментов на базе JavaScript. Убедитесь, что Node.js установлен на вашей машине для разработки. Вы можете скачать и установить Node.js с официального сайта: Загрузки Node.js.
Настройте среду проекта React Native на вашей машине, если вы еще этого не сделали. Вы можете следовать официальной документации React Native для инструкций по настройке вашей среды разработки: React Native — Начало работы.
Шаг 1: Настройка AWS SDK
Во-первых, установите пакет aws4-react-native
, который предоставляет необходимые инструменты для подписи запросов AWS в приложениях React Native. Кроме того, установите библиотеку react-native-fast-image
, которая предоставляет высокопроизводительный и настраиваемый компонент изображения для приложений React Native. Эта библиотека предназначена для быстрого рендеринга изображений и включает такие полезные возможности, как кэширование.
npm install aws4-react-native
npm install react-native-fast-image
Шаг 2: Напишите функцию предварительной подписи
Создайте функцию, которая генерирует предварительно подписанный URL-адрес для заданного объекта S3. Эта функция будет использовать библиотеку aws4
для подписи запроса.
Предположим, что наши изображения имеют следующие URL-адреса:
'https://s3.bucket-name.com/compressed-images/your-image-key.webp';
Где:
"s3.bucket-name.com" — это имя хоста корзины S3
"compressed-images/your-image-key.webp" — остальная часть URL-адреса — путь к изображению
"your-image-key.webp" — это ключ изображения
// helpers/generate-presigned-urls.ts
// Импорт необходимых модулей
var aws4 = require('aws4-react-native');
// Функция для генерации предварительно подписанного URL
export function generatePreSignedUrl(imageUrl, expirationSeconds = 3600) {
// Извлечение ключа объекта из URL изображения
const parts = imageUrl.split('/');
const lastPart = parts[parts.length - 1];
const path = 'compressed-images/' + lastPart;
// Определение опций для подписи
const opts = {
service: 's3',
region: 'your-region', // например, eu-west-2
path: path,
host: 'your-s3-host', // в нашем случае s3.bucket-name.com
};
// Подпись запроса
aws4.sign(opts, {
accessKeyId: 'ACCESS_KEY',
secretAccessKey: 'SECRET_KEY',
});
// Возвращение подписанных заголовков
return {
Authorization: opts.headers.Authorization,
X_Amz_Date: opts.headers['X-Amz-Date'],
};
}
Результат будет примерно таким:
const imageUrl = 'https://s3.bucket-name.com/compressed-images/your-image-key.webp';
const presignedUrl = generatePreSignedUrl(imageUrl);
console.log("Pre-signed URL:", presignedUrl);
Pre-signed URL: https://s3.REGION.amazonaws.com/s3.bucket-name.com/compressed-images/your-image-key.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ACCESS_KEYaws4_request&X-Amz-Date=20231018T075941Z&X-Amz-Expires=3600&X-Amz-Signature=SIGNATURE-SignedHeaders=host
Шаг 3: Создайте компонент изображения
import React from 'react';
import { ActivityIndicator, ImageStyle, StyleProp, StyleSheet, View } from 'react-native';
import FastImage from 'react-native-fast-image';
import { generatePreSignedUrl } from 'helpers/generate-presigned-url'; // ранее созданная функция для генерации предварительно подписанных URL
interface Props {
imageURL: string;
style: StyleProp<ImageStyle>;
resizeMode: 'contain' | 'cover' | 'stretch';
}
export const AWSS3Image = React.memo((props: Props) => {
const [isLoading, setIsLoading] = React.useState(true);
const presignedURL = React.useMemo(() => {
return generatePreSignedUrl(props.imageURL);
}, [props.imageURL]);
const onLoading = () => {
setIsLoading(false);
};
return (
<FastImage
source={{
uri: props.imageURL,
headers: {
'X-Amz-Content-Sha256':
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', // хеш пустой строки, остается неизменным для всех реализаций
'X-Amz-Date': presignedURL.X_Amz_Date,
Authorization: presignedURL.Authorization,
},
}}
style={props.style}
resizeMode={props.resizeMode}
onLoad={onLoading}>
{isLoading && (
<View style={styles.loaderContainer}>
<ActivityIndicator size="large" />
</View>
)}
</FastImage>
);
});
const styles = StyleSheet.create({
loaderContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
Заголовок 'X-Amz-Content-Sha256'
со значением 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
связан с SHA-256 хешем пустой строки. Это значение хеша представляет содержимое полезной нагрузки запроса, которое в контексте генерации предварительно подписанных URL-адресов для AWS S3 часто является пустой строкой. Это значение остается постоянным во всех реализациях и важно для поддержания целостности запроса и обеспечения успешной аутентификации с AWS S3.
Шаг 4: Использование
Теперь вы можете использовать компонент AWSS3Image
в вашем приложении React Native для безопасного отображения изображений из AWS S3
.
import React from 'react';
import { View, ImageStyle, StyleProp } from 'react-native';
import { AWSS3Image } from './path/to/aws-s3-image';
const App = () => {
return (
<View>
<AWSS3Image
imageURL="https://your-s3-bucket-url/image.jpg"
style={styles.image}
resizeMode="cover"
/>
</View>
);
};
const styles = {
image: {
width: 200,
height: 200,
} as StyleProp<ImageStyle>,
};
export default App;
Заключение
В заключение, эта статья предоставила практическое руководство по реализации предварительно подписанных URL-адресов в приложениях React Native для доступа к защищенным ресурсам, хранящимся в AWS S3. Мы рассмотрели процесс программной генерации предварительно подписанных URL-адресов с помощью SDK AWS, а также интеграцию библиотеки react-native-fast-image для эффективного рендеринга изображений. Следуя
этим шагам, разработчики могут безопасно предоставлять временный доступ к определенным ресурсам S3, обеспечивая при этом оптимальную производительность в приложениях React Native.