Шифрование обеспечивает безопасность данных за счет скремблирования, так что только авторизованные люди могут получить доступ и расшифровать информацию или данные.


Что мы будем строить

В этом посте обсуждается использование функции базы данных Appwrite для создания приложения чата. В этой статье мы обеспечим безопасность данных, используя библиотеку cryptr для шифрования и дешифрования строк.

URL-адрес GitHub


Предпосылки

Эта статья является второй частью серии из двух частей, в которой описывается создание чата со сквозным шифрованием с помощью Appwrite в приложении Next.js. Крайне важно начать с первой части, чтобы получить максимальную отдачу от этой статьи. Ознакомьтесь с первой частью статьи здесь.


Установка криптора

крипта это просто aes-256-gcm модуль для шифрования и дешифрования значений строк UTF-8.

Чтобы установить crypt, запустите эту команду терминала в каталоге нашего проекта.

    npm install cryptr
Войти в полноэкранный режим

Выйти из полноэкранного режима


Создание коллекции и атрибутов

В левой части приложения Приставка приборной панели, нажмите на Вкладка базы данных.

Панель управления Appwrite Console

Нажми на Добавить базу данных Кнопка для создания новой базы данных. Создание новой базы данных приведет нас к Коллекция страница.

Далее мы создадим коллекцию на вкладке нашей базы данных, щелкнув значок Добавить коллекцию кнопка. Это действие перенаправляет нас на Разрешения страница.

Консоль записи приложений

В Уровень коллекции, мы хотим назначить Доступ для чтения а также Доступ для записи с роль: все ценность. Мы можем настроить эти роли позже, чтобы указать, кто имеет доступ для чтения или записи в нашу базу данных.

Консоль записи приложений

С правой стороны Разрешения страницу, скопируйте Идентификатор коллекциикоторый нам понадобится для выполнения операций над документами коллекции.

Затем перейдите на вкладку атрибутов, чтобы создать свойства, которые мы хотим, чтобы документ имел.

Консоль записи приложений

Давайте создадим строковый атрибут сообщение размером 256 бит.

Консоль записи приложений

Консоль записи приложений


Добавление взаимодействия приложения чата с базой данных

в chat.jsx файл внутри pages папку, импортируйте хук useState для обработки состояний, Appwrite’s client экземпляр и Appwrite Databases метод.

    import {  useState } from 'react';
    import { client} from '../init' 
    import { Databases } from 'appwrite';
Войти в полноэкранный режим

Выйти из полноэкранного режима

Затем создайте две переменные состояния:

  • А messages переменная состояния для хранения сообщений, которые пользователь собирается отправить.
  • А databaseMessages переменная состояния для хранения сообщений, полученных из базы данных.
    const [message, setMessages] = useState("");
    const [databaseMessages, setDatabaseMessages] = useState(["hey"])
Войти в полноэкранный режим

Выйти из полноэкранного режима

Затем мы создаем databases экземпляр с помощью Appwrite Databases метод. Этот Databases Метод получает клиент и идентификатор базы данных в качестве параметров.

    const databases = new Databases(client, 'DatabaseID');
Войти в полноэкранный режим

Выйти из полноэкранного режима

Далее мы создаем listMessages функция и sendMessage функция.

    const listMessages = async () => {
      const promise = await databases.listDocuments('CollectionID');
      promise.documents.map((document) => setDatabaseMessages(prevArray => [...prevArray, document.message]))
    }
Войти в полноэкранный режим

Выйти из полноэкранного режима

listMessages в блоке кода выше делает следующее:

  • Перечисляет все документы в коллекции с помощью Appwrite. listDocuments метод. Этот listDocuments Метод получает идентификатор коллекции в качестве параметра.
  • Обновляет databaseMessages переменная состояния с сообщениями, сохраненными в документах.
    const sendMessage = async () => {
      try {
        await databases.createDocument('CollectionID', 'unique()', {
          "message": message
        });
        alert('message sent')
        setMessages("")
        listMessages()
       }catch (error) {
        console.log(error)
      }
    }
Войти в полноэкранный режим

Выйти из полноэкранного режима

sendMessage функция выше делает следующее:

  • Создает новый документ, используя Appwrite createDocument() функция. Этот createDocument() Функция получает идентификатор коллекции, строку unique() и значения атрибутов в качестве параметров.
  • Предупреждает нас, когда мы успешно сохранили сообщение.
  • Очищает message переменная и вызывает listMessages() функция.
  • Записывает все обнаруженные ошибки на консоль.

Далее проверяем, соответствует ли databaseMessages массив пуст, то мы перебираем данные в databaseMessages массив и отображать сообщения в нашем приложении чата.

    <div className='messages'>
       {
        databaseMessages ? (
          <div className="message-container">
             {
               databaseMessages.map((databaseMessage)=> (
                <div className="user-message">{databaseMessage}</div>
              ))
            } 
          </div>
        ) : null
      } 
    </div>
Войти в полноэкранный режим

Выйти из полноэкранного режима

Далее мы пройдем message переменная в качестве значения для нашего поля ввода и нашего sendMessage функции для onClick прослушиватель событий на нашем Отправить кнопка.

    <div className='input-area'>
      <input type="text" className='message-input' value={message} onChange={(e) => setMessages(e.target.value)}/>
      <button className='send' type='button' onClick={sendMessage}>send</button>
    </div>
Войти в полноэкранный режим

Выйти из полноэкранного режима

После того, как мы закончим с этим разделом, вот как chat.jsx файл выглядит.

    import {  useState } from 'react';
    import { client} from '../init' 
    import { Databases } from 'appwrite';

    const Chat = () => {
      const [message, setMessages] = useState("");
      const [databaseMessages, setDatabaseMessages] = useState(["hey"])

      const databases = new Databases(client, 'DatabaseID');

      const listMessages = async () => {
        const promise = await databases.listDocuments('CollectionID');
        promise.documents.map((document) => setDatabaseMessages(prevArray => [...prevArray, document.message]))
      }

      const sendMessage = async () => {
        try {
          await databases.createDocument('CollectionID', 'unique()', {
            "message": message
          });
          alert('message sent')
          setMessages("")
          listMessages()
        } catch (error) {
          console.log(error)
        }
      }

      return (
        <div className='chat'>
          <div className='user-chat'>
            <div className="user-chat-header">USER</div>
            <div className='messages'>
              {
                databaseMessages.map((databaseMessage)=> (
                  <div className="user-message">{databaseMessage}</div>
                ))
              }
            </div>
            <div className='input-area'>
              <input type="text" className='message-input' value={message} onChange={(e) => setMessages(e.target.value)}/>
              <button className='send' type='button' onClick={sendMessage}>send</button>
            </div>
          </div>
        </div>
      ) 
    };
    export default Chat;
Войти в полноэкранный режим

Выйти из полноэкранного режима

Вот как выглядит наше приложение для чата.

Приложение для чата


Шифрование

Cryptr требует секретный ключ для шифрования или расшифровки строки. В корне нашего проекта мы создаем .env.local файл, который будет содержать наш секретный ключ.

    ## .env.local

    NEXT_PUBLIC_KEY = "********"
Войти в полноэкранный режим

Выйти из полноэкранного режима

Использование префикса «NEXT_PUBLIC» при сохранении нашего секретного ключа позволяет сделать переменную среды доступной в нашем компоненте.

Далее мы импортируем склеп библиотека в нашем chat.jsx файл.

    import {  useEffect, useState } from 'react';
    import { client} from '../init' 
    import { Databases } from 'appwrite';

    const Cryptr = require('cryptr');
Войти в полноэкранный режим

Выйти из полноэкранного режима

Затем мы создаем экземпляр cryptr для шифрования и расшифровки нашей строки с использованием нашего секретного ключа.

    import {  useEffect, useState } from 'react';
    import { client} from '../init' 
    import { Databases } from 'appwrite';
    const Cryptr = require('cryptr');

    const Chat = () => {
      ...  
      const cryptr = new Cryptr(process.env.NEXT_PUBLIC_KEY);
      return (
        ...
       ) 
    };
Войти в полноэкранный режим

Выйти из полноэкранного режима

sendMessages функция в нашем chat.jsx файл будет отвечать за шифрование данных. Библиотека crypt позволяет нам использовать encrypt функция для шифрования строк в нашем приложении.

    const sendMessage = async () => {
      // encrypt the string in our message state variable
      const encryptedMessage = cryptr.encrypt(message)
       try {
        await databases.createDocument('62dc54f155f11d4c38cb', 'unique()', {
        // stores the encrypted message instead of the original message
           "message": encryptedMessage
         });
         alert('message sent')
         setMessages("")
         listMessages()
       } catch (error) {
        console.log(error)
      }
    }
Войти в полноэкранный режим

Выйти из полноэкранного режима

sendMessage функция шифрует данные в message state, а затем сохраняет зашифрованные данные в нашей базе данных Appwrite.

Приложение для чата

Сообщение «привет» шифруется и сохраняется в нашей базе данных в виде набора чисел.

База данных приложений

Затем мы извлечем зашифрованные данные из нашей базы данных и расшифруем их, чтобы получить исходное сообщение.

в listMessages Теперь мы расшифруем сообщение, полученное из базы данных Appwrite.

    const listMessages = async () => {
      const promise = await databases.listDocuments('62dc54f155f11d4c38cb');
      setDatabaseMessages([])
      promise.documents.map((document) =>{ 
      // map through the documents in the collection and decrypt each message
        const decryptedMessage = cryptr.decrypt(document.message)
        setDatabaseMessages(prevArray => [...prevArray, decryptedMessage])
      }
       )
    }
Войти в полноэкранный режим

Выйти из полноэкранного режима

listMessages функция очищает databaseMessages массив перед зацикливанием и расшифровкой сообщений в документе.

Консоль базы данных Appwrite

Вот как должно выглядеть наше чат-приложение.

База данных приложений


Вывод

В этой статье обсуждалось создание сквозного зашифрованного чата с помощью cryptr и Appwrite.


Ресурсы