Пошаговое руководство по предварительной подписи URL-адресов AWS S3 и получению защищенных изображений S3 в React Native

от автора

Получение защищенных изображений AWS S3 в React Native

Получение защищенных изображений AWS S3 в React Native

Введение

В современных приложениях, особенно работающих с мультимедийным контентом, эффективное управление такими ресурсами, как изображения, имеет решающее значение для плавного пользовательского опыта. 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.


ссылка на оригинал статьи https://habr.com/ru/articles/850812/