Как создать приложение для чата со сквозным шифрованием в Next.js: настройка и авторизация

Текстовые сообщения развивались в течение последнего десятилетия, став основным источником электронной коммуникации. Поскольку этот носитель все чаще выбирают в качестве средства передачи важной информации, становится все более необходимым контролировать, к какой информации пользователь может получить доступ.

Что мы будем создавать

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

URL GitHub

https://github.com/Iheanacho-ai/chat-app-nextjs

Предварительные условия

Чтобы извлечь максимальную пользу из этой статьи, вам понадобится следующее:

  • Базовое понимание CSS, JavaScript и React.js.
  • Docker Desktop установлен на вашем компьютере; выполните команду docker -v, чтобы проверить, установлен ли у нас Docker Desktop. Если нет, установите его из документации Get Docker.
  • Экземпляр Appwrite, запущенный на вашем компьютере. Ознакомьтесь с этой статьей, чтобы создать локальный экземпляр Appwrite. Мы будем использовать мощную службу учетных записей Appwrite для аутентификации и управления учетными записями пользователей.

Настройка нашего приложения Next.js

Next.js — это фреймворк React с открытым исходным кодом, который позволяет нам создавать статические веб-приложения с рендерингом на стороне сервера.

Чтобы создать наше приложение Next.js, перейдите в нужную директорию и выполните приведенную ниже команду терминала:

    npx create-next-app@latest
    # or
    yarn create next-app
Войти в полноэкранный режим Выйти из полноэкранного режима

После создания нашего приложения измените директорию на проект и запустите сервер разработки командой ниже.

    cd <name of our project>
    npm run dev
Войти в полноэкранный режим Выйти из полноэкранного режима

Чтобы увидеть наше приложение, перейдите по адресу http://localhost:3000.

Установка Appwrite

Appwrite — это сквозное серверное решение с открытым исходным кодом, которое позволяет разработчикам быстрее создавать приложения.

Чтобы использовать Appwrite в нашем приложении Next.js, установите Appwrite client-side SDK для веб-приложений:

    npm install appwrite
Войдите в полноэкранный режим Выйти из полноэкранного режима

Создание нового проекта Appwrite

При создании экземпляра Appwrite мы указали имя хоста и порт, на котором будет работать наша консоль. По умолчанию это localhost:80.

Перейдите на localhost:80 и создайте новую учетную запись, чтобы увидеть консоль.

На нашей консоли мы видим кнопку Create Project. Нажмите на нее, чтобы начать новый проект.

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

Теперь скопируйте ID проекта и API Endpoint, которые нужны нам для инициализации Appwrite Web SDK.

Далее мы создадим файл init.js в корневом каталоге нашего проекта для инициализации Appwrite Web SDK.

    import { Client, Account } from "appwrite";
    import Router from 'next/router'; 

    export const client = new Client();
    export const account = new Account(client);

    client
        .setEndpoint('http://localhost/v1') // Your API Endpoint
        .setProject('62d9859fd5a5923edf53') // Your project ID
    ;

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

Создание интерфейса регистрации

Теперь нам нужно создать форму регистрации для наших пользователей в файле pages/index.jsx нашего проекта.

    import Link from 'next/link';

    const Home = () => {
      return (
        <div>
          <div className="signup">
            <h2 className='form-h2'>Sign up</h2>
            <form action="">
              <label htmlFor="name">Name</label>
              <input type="text" className='signup-input' name="name" id="" />
              <label htmlFor="email">Email</label>
              <input type="email" className='signup-input' name="email" id=""/>
              <label htmlFor="password">Password</label>
              <input type="password" className='signup-input' name="password" id=""/>
              <label htmlFor="password">Confirm Password</label>
              <input type="password" className='signup-input' name="confirm password" id=""/>
              <button type='button' className= "button">Sign Up</button>
              <p>Already have an account, <Link href="/signin" className='link'>Sign in</Link></p>
            </form>
          </div>
        </div>
      )
    };
    export default Home;
Вход в полноэкранный режим Выход из полноэкранного режима

Далее переходим в папку styles в корневом каталоге нашего проекта, эта папка содержит файл global.css. В файле styles/global.css мы добавим стили для нашей формы регистрации.

https://gist.github.com/Iheanacho-ai/982cc4762bb129965e4a03a23a110256

Вот как выглядит наша форма регистрации.

Создание интерфейса регистрации

Если пользователь уже создал аккаунт в нашем приложении, то нам нужно создать страницу регистрации, чтобы пользователи могли войти в свой аккаунт.

Сначала создайте файл signin.jsx в папке pages. Этот файл pages/signin.jsx будет содержать часть кода в блоке кода ниже.

    const Home = () => {
      return (
        <div>
          <div className="signin">
            <h2 className='form-h2'>Sign in </h2>
            <form action="">
              <label htmlFor="email">Email</label>
              <input type="email" name= "email" className='signup-input' id=""/>
              <label htmlFor="password">Password</label>
              <input type="password" className='signup-input' name="password" id=""/>
              <button type='button' className= "button">Sign in</button>
            </form>
          </div>
        </div>
      )
    };
    export default Home;
Вход в полноэкранный режим Выход из полноэкранного режима

Далее добавьте стиль на страницу регистрации.

    .signup, .signin{
      width: 400px;
      display: flex;
      flex-flow: column;
      justify-content: center;
      text-align: left;
      background: #fff;
      box-shadow: 0 10px 30px rgba(0,0,0,0.1);
      border-radius: 7px;
      margin: 10% auto;
      padding: 30px;
    }
Вход в полноэкранный режим Выход из полноэкранного режима

Перейдите на сайт http://localhost:3000/signin, чтобы увидеть нашу страницу регистрации.

Аутентификация пользователей

В этом разделе статьи мы обсудим использование формы для создания, аутентификации и регистрации пользователей.

Регистрация пользователей
В файле pages/index.jsx импортируйте хук React useState для обработки состояний в нашем приложении.

    import { useState } from 'react';
    import Link from 'next/link';
Вход в полноэкранный режим Выход из полноэкранного режима

Далее создайте переменные состояния для хранения значений формы в файле pages/index.jsx.

    const [name, setName] = useState()
    const [email, setEmail] = useState();
    const [password, setPassword] = useState();
    const [confirmPassword, setConfirmPassword] = useState();
Вход в полноэкранный режим Выйти из полноэкранного режима

Переменные состояния делают следующее:

  • Переменная name хранит имя пользователя, создающего аккаунт в нашем приложении.
  • Переменная email хранит электронную почту пользователя
  • Переменные password и confirmPassword хранят пароль к учетной записи пользователя.

Далее мы напишем функцию signupWithEmailandPassword для создания учетной записи для нового пользователя.

    const signupWithEmailandPassword = async () => {
      if (password.length >= 8) {
        if (password === confirmPassword) {
          try {
            await account.create('unique()', email, password, name)
          }catch (error) {
            console.log(error)
          }
        }else {
          alert("password do not match")
        }
      } else {
         alert('Password length should be up to 8 characters')
      }
    }
Вход в полноэкранный режим Выход из полноэкранного режима

Функция signupWithEmailandPassword делает следующее:

  • Проверяет, равен ли пароль пользователя восьми символам или превышает их.
  • Проверяет, одинаковы ли password и confirmPassword.
  • Создает новую учетную запись пользователя с указанием его электронной почты, пароля и имени
  • Записывает все возникшие ошибки в консоль

Далее передайте переменные состояния в качестве значений полям ввода и функцию signupWithEmailandPassword слушателю события onClick на нашей кнопке Sign up.

    <form action="">
        <label htmlFor="name">Name</label>
        <input type="text" className='signup-input' name="name" value={name} onChange={(e) => setName(e.target.value)} id="" />
       <label htmlFor="email">Email</label>
        <input type="email" className='signup-input' name="email" value={email} onChange={(e) => setEmail(e.target.value)} id=""/>
        <label htmlFor="password">Password</label>
       <input type="password" className='signup-input' name="password" value={password} onChange={(e) => setPassword(e.target.value)} id=""/>
        <label htmlFor="password">Confirm Password</label>
        <input type="password" className='signup-input' name="confirm password" value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} id=""/>
        <button type='button' className= "button" onClick={signupWithEmailandPassword}>Sign Up</button>
       <p>Already have an account, <Link href="/signin" className='link'>Sign in</Link></p>
    </form>
Вход в полноэкранный режим Выход из полноэкранного режима

Вот как выглядит наш файл index.jsx.

https://gist.github.com/Iheanacho-ai/72acee318020e43f85de09d17c5d73a9

Заполните форму для создания учетной записи в приложении.

Чтобы просмотреть список пользователей, создавших учетные записи в нашем приложении, перейдем на вкладку Users в Appwrite Dashboard.

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

Для регистрации пользователей мы создадим функцию signinWithEmailandPassword в файле init.js.

    import { Client, Account } from "appwrite";
    import Router from 'next/router'; 
    export const client = new Client();
    export const account = new Account(client);

    client
        .setEndpoint('http://localhost/v1') // Your API Endpoint
        .setProject('62d9859fd5a5923edf53') // Your project ID
    ;

    export const signinWithEmailandPassword = async (email, password) => {
        try {
            await account.createEmailSession(email, password)
            Router.push("/chat")
        } catch (error) {
            console.log(error)
        }
    }
Вход в полноэкранный режим Выход из полноэкранного режима

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

  • Создает сессию пользователя с помощью функции Appwrite createEmailSession. Эта функция получает параметры электронной почты и пароля.
  • Переходит к маршруту чата после того, как пользователь зарегистрировался.
  • Записывает в консоль все возникшие ошибки.

Сразу после создания учетной записи мы хотим, чтобы пользователь вошел в наше приложение. Для этого импортируйте функцию signinWithEmailandPassword в файл pages/index.jsx.

    import { account, signinWithEmailandPassword } from '../init';
Вход в полноэкранный режим Выход из полноэкранного режима

Далее вызовем функцию signinWithEmailandPassword в функции signupWithEmailandPassword.

    const signupWithEmailandPassword = async () => {
       if (password.length >= 8) {
        if (password === confirmPassword) {
          try {
            await account.create('unique()', email, password, name)
             alert("account created successfully")
            // signes in the user
            signinWithEmailandPassword(email, password)    
           } catch (error) {
            console.log(error)
          }
         } else {
         alert("password do not match")
        }
      } else {
         alert('Password length should be up to 8 characters')
      }
    }
Вход в полноэкранный режим Выход из полноэкранного режима

Затем мы импортируем функцию signinWithEmailandPassword в наш файл pages/signin.jsx.

    import { useState } from 'react';
    import { signinWithEmailandPassword } from '../init';
Вход в полноэкранный режим Выход из полноэкранного режима

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

    const [email, setEmail] = useState();
    const [password, setPassword] = useState();
Вход в полноэкранный режим Выход из полноэкранного режима

После создания переменных состояния создайте функцию handleSignin, которая вызывает функцию signinWithEmailandPassword.

    const handleSignin = () => {
      signinWithEmailandPassword(email, password)
    }
Вход в полноэкранный режим Выход из полноэкранного режима

Затем мы передаем переменные состояния в качестве значений полям ввода и функцию handleSignin слушателю события onClick на нашей кнопке Sign in.

    <div>
      <div className="signin">
        <form action="">
          <label htmlFor="email">Email</label>
          <input type="email" className='signup-input' name="email" value={email} onChange={(e) => setEmail(e.target.value)} id=""/>
          <label htmlFor="password">Password</label>
          <input type="password" className='signup-input' name="" value={password} onChange={(e) => setPassword(e.target.value)} id=""/>
            <button type='button' className= "button" onClick={handleSignin}>Sign in</button>
        </form>
      </div>
    </div>
Вход в полноэкранный режим Выход из полноэкранного режима

Вот как должен выглядеть наш файл pages/signin.jsx на этом этапе.

    import { useState } from 'react';
    import { signinWithEmailandPassword } from '../init';

    const Home = () => {
      const [email, setEmail] = useState();
      const [password, setPassword] = useState();
      const handleSignin = () => {
        signinWithEmailandPassword(email, password)
      }
      return (
        <div>
          <div className="signin">
            <form action="">
              <label htmlFor="email">Email</label>
              <input type="email" className='signup-input' name="email" value={email} onChange={(e) => setEmail(e.target.value)} id=""/>
              <label htmlFor="password">Password</label>
              <input type="password" className='signup-input' name="" value={password} onChange={(e) => setPassword(e.target.value)} id=""/>
              <button type='button' className= "button" onClick={handleSignin}>Sign in</button>
            </form>
          </div>
        </div>
      )
    };

    export default Home;
Вход в полноэкранный режим Выход из полноэкранного режима

Создание интерфейса чата

Давайте создадим файл chat.jsx в папке pages. Этот файл будет содержать приведенный ниже фрагмент кода.

    const Chat = () => {
      return (
        <div className='chat'>
          <div className='user-chat'>
            <div className="user-chat-header">USER</div>
            <div className='messages'>
            </div>
            <div className='input-area'>
              <input type="text" className='message-input'/>
              <button className='send' type='button'>send</button>
            </div>
          </div>
        </div>
      ) 
    };

   export default Chat;
Вход в полноэкранный режим Выйти из полноэкранного режима

В файле global.css мы добавим стили для интерфейса чата.

https://gist.github.com/Iheanacho-ai/93956e8a24effe332efe44e4d15a8347

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

Заключение

В этой статье мы рассмотрели использование службы Appwrite’s Account для аутентификации и подписи пользователя в приложении.

Ресурсы

  • Создание локального экземпляра Appwrite в 3 шага — Начало работы с Appwrite для Web
  • API учетной записи

Оцените статью
devanswers.ru
Добавить комментарий