Аутентификация с помощью Appwrite в React — часть 2

Аутентификация пользователей — это всегда хорошо.
Но создание собственных правил и функций аутентификации и их реализация требуют больших усилий.

Но зачем проходить через все эти трудности, если Appwrite находится совсем рядом?

В своем предыдущем посте я рассказал о процессе установки. Но теперь пришло время для самого процесса!

Итак, запустите вашу любимую IDE (у меня это VS Code), потягивайте кофе и приступайте к работе.

Шаг 1 : Настройка службы Appwrite

Чтобы начать использовать функции Appwrite, нам необходимо инициализировать SDK.
Для этого вам понадобится ваш projectId и endpoint (иначе Appwrite не будет знать, кто вы).

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

Примечание : Создайте папку services и создайте здесь файл AppwriteService.js.

Добавьте следующий код :

import { Appwrite } from "appwrite";

const config = {
    projectId : process.env.REACT_APP_APPWRITE_PROJECT,
    endpoint :  process.env.REACT_APP_APPWRITE_ENDPOINT,
};


const appwrite = new Appwrite();

class AppwriteService {
    constructor() {
        appwrite.setEndpoint(config.endpoint).setProject(config.projectId);
    }
}

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

Как вы можете видеть, мы добавляем конечную точку и projectId для нашего проекта.

Теперь, когда у нас есть идентификатор, который Appwrite может распознать, мы можем продолжить.

Шаг 2: Реализация API аутентификации

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

  • Создание пользователя
  • Вход пользователя
  • Выход пользователя из системы

А именно, Регистрация, Вход и Выход.

  • Создайте свойство учетной записи, отвечающее за обработку вызовов Auth API
  • определите методы аутентификации для регистрации, входа и выхода.

Обновите файл службы Appwrite этим кодом.

import { Appwrite } from "appwrite";

const config = {
    projectId : process.env.REACT_APP_APPWRITE_PROJECT,
    endpoint :  process.env.REACT_APP_APPWRITE_ENDPOINT,
    bucketId : process.env.REACT_APP_APPWRITE_BUCKET
};


const appwrite = new Appwrite();

class AppwriteService {
    constructor() {
        appwrite.setEndpoint(config.endpoint).setProject(config.projectId);

        this.account = appwrite.account;
    }

    createAccount = (email, name, password) =>{
        return this.account.create("unique()",email, password,name)
    }

    loginUser = (email, password) =>{
        return this.account.createSession(email,password);
    }

    logoutUser = () =>{
        return this.account.deleteSession('current');
    }

}

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

Вы можете узнать больше о вышеуказанных функциях здесь 👉👉 Accounts API

Здесь следует обратить внимание на строку unique(), переданную в функции account.create() выше. Она используется для указания того, что :

Вы можете использовать Appwrite для автоматической генерации уникального USER_ID для каждого нового пользователя. Вы также можете передать свой собственный UniqueId. Но опять же, зачем делать то, о чем уже позаботились?

Шаг 3: Создание различных компонентов

Теперь, когда у нас есть готовые функции, следующим шагом будет их использование.
Создайте компоненты для Signup, Login и Navbar с опцией Logout. Вы можете создать их в своем собственном дизайне.

Главная задача — обеспечить маршрутизацию для различных страниц. Для этого мы будем использовать React router. Поэтому первым шагом будет его установка в ваш проект.

npm install react-router-dom@6
Вход в полноэкранный режим Выйти из полноэкранного режима

Затем нам нужно будет указать маршруты следующим образом:

import {Routes , Route } from 'react-router-dom';
import './App.css';
import Home from './Components/Home';
import Login from './Components/Login';
import Signup from './Components/Signup';
import Navbar from './Components/Navbar';

function App() {
  return (
      <div className="App">
      <Routes>
      <Route exact path={'/'} element={<><Navbar/>
        <Home/></>} />
        <ImageFilter/></>} />
      <Route exact path={'/signup'} element={<Signup/>}/>
      <Route exact path={'/login'} element={<Login/>}/>
    </Routes>
    </div>
  );
}

export default App;

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

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

Шаг 4: Обеспечить Appwrite в React

Чтобы использовать методы аутентификации, нам необходимо иметь доступ к классу службы Appwrite.

Простой» подход заключается в создании экземпляра Appwrite в каждом компоненте React, который должен использовать Appwrite. Однако это плохой подход по двум причинам:

  • Будет сложно тестировать наши компоненты.
  • Он более склонен к ошибкам. В итоге мы получим несколько экземпляров. Наш класс службы Appwrite должен быть инициализирован только один раз (Simpleton Pattern).

Лучшим подходом будет использование React's Context API для предоставления экземпляра Appwrite один раз на верхнем уровне иерархии наших компонентов. Создайте новый файл src/context/Appwrite/index.js в вашем проекте React и добавьте следующее:

import React from 'react';

const AppwriteContext = React.createContext(null);

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

Затем мы создадим хорошо инкапсулированный модуль Appwrite, определив новый файл src/components/Appwrite/index.js, который экспортирует класс AppwriteService и AppwriteContext.

import AppwriteContext from '../../context/Appwrite';
import Appwrite from '../../services/AppwriteService';

export default Appwrite;

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

Метод React.createContext() в src/context/Appwrite/index.js создает два компонента, AppwriteContext.Provider, который используется для предоставления экземпляра Appwrite один раз в вершине нашего дерева компонентов, и AppwriteContext.Consumer для каждого компонента, которому требуется доступ к Appwrite.

Мы будем использовать компонент AppwriteContext.Provider для предоставления экземпляра Appwrite всему приложению, обернув его вокруг нашего корневого компонента в /src/index.js, как показано ниже:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import Appwrite, {AppwriteContext} from './Components/Appwrite';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <BrowserRouter>
     <AppwriteContext.Provider value={new Appwrite()}>
        <App />
        </AppwriteContext.Provider>
    </BrowserRouter>
);
Вход в полноэкранный режим Выход из полноэкранного режима

Здесь Appwrite инстанцируется один раз и внедряется в наше дерево компонентов через React Context API. Теперь каждый компонент, которому требуется доступ к Appwrite. Мы можем сделать это с помощью API useContext, предоставляемого React. Код выглядит примерно так:

import React, {useContext} from 'react';

import {AppwriteContext} from './components/Appwrite';

const SomeExampleComponent = () => {
    const appwrite = useContext(AppwriteContext);
   return (
    <div>This component has access to Appwrite.</div>
   );
}

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

Шаг 5: Регистрация и вход

Теперь, когда мы знаем, как использовать контекст Appwrite, пришло время использовать его на практике.

Для регистрации нам нужно 3 параметра: имя, email и пароль.
Мы будем использовать форму и состояния для получения данных.

Простая форма регистрации вместе с состояниями и слушателями событий onChange, мы готовы использовать метод Appwrite createAccount. Поскольку он возвращает обещание, нам нужно использовать блок then и catch.

Но чтобы это сработало, мы должны импортировать контекст Appwrite и consume его. Как говорилось выше, мы реализуем это с помощью API useContext.

Код будет выглядеть примерно так:

import React, { useContext, useState } from 'react'
import SignupImg from "../Assets/Signup.png"
import "../Css/Signup.css"
import Pig from "../Assets/pig.png"
import { useNavigate } from 'react-router-dom';
import { AppwriteContext } from './Appwrite';

function Signup() {
    const [name,setName] = useState("");
    const [email,setEmail] = useState("");
    const [password,setPassword] = useState("");

    const navigator = useNavigate();
    const appwrite = useContext(AppwriteContext);

    const handleSignup = (e) => {
        e.preventDefault();
        if(name === '' || email==='' || password === ''){
            alert('All fields are required');
            return;
        }

        appwrite.createAccount(email, name, password).then((res) =>{
            console.log('Success', res);
            window.location="/"
        }).catch((error) =>{
            console.log('Error', error);
        })
    }
   return (
    <div className='Signup'>
        <div className='Signup-left'>
        <div className='signup-home'>
                <img className='signup-home-btn' onClick={()=>{
                    navigator("/");
                }} src={Pig} alt="pigshell"/>
            </div>
            <div className='Signup-head'>
                <div>Sign Up</div>
                <div className='Signup-subhead'>
                    Create account to access images from anywhere
                </div>
            </div>
            <div className='Signup-card'>
                <form className='Signup-form'>
                    {/* <label for="name">Your Name</label> */}
                    <input className='Signup-input' name='name' placeholder='Name' id='signup-name' autoComplete='off' value={name} onChange={(e)=>{
                        setName(e.target.value);
                    }}/>
                    <input className='Signup-input' placeholder='Email' autoComplete='off' id='signup-email' value={email} onChange={(e)=>{
                        setEmail(e.target.value);
                    }}/>
                    <input className='Signup-input' placeholder='Password' type='password' autoComplete='off' id='signup-password' value={password} onChange={(e)=>{
                        setPassword(e.target.value);
                    }}/>
                    <button type="submit" id='signup-btn' 
                    onClick={handleSignup}>Create Account</button>
                </form>
            </div>
            <div className='Signup-footer'>
                <p>Already have account? <a className='login-redirect highlight-text' href='/login'>Login Now</a></p>
            </div>
        </div>
        <div className='Signup-right'>
        <div className='Signup-welcome'>
        <h2>Welcome to PigShell</h2>
            <p>Start your journey full of Piggy Awesomeness!</p>
        </div>
        <div className='Signup-img'>
            <img src={SignupImg} alt='signup'/>
        </div>
        </div>
    </div>
  )
}

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

С помощью некоторых CSS страница будет выглядеть следующим образом:

Дайте мне знать, если вам понравился дизайн!!!

Код для использования метода создания учетной записи Appwrite выглядит следующим образом:

const handleSignup = (e) => {
        e.preventDefault();
        if(name === '' || email==='' || password === ''){
            alert('All fields are required');
            return;
        }

        appwrite.createAccount(email, name, password).then((res) =>{
            console.log('Success', res);
            window.location="/"
        }).catch((error) =>{
            console.log('Error', error);
        })
    }

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

Аналогичным образом мы можем реализовать функцию Login.
Код компонента выглядит следующим образом:

import React, { useContext, useState } from 'react'
import LoginImg from "../Assets/Signup.png"
import "../Css/Login.css"
import Pig from "../Assets/pig.png"
import { useNavigate } from 'react-router-dom';
import { AppwriteContext } from './Appwrite';

function Login() {
    const [email,setEmail] = useState("");
    const [password,setPassword] = useState("");

    const navigator = useNavigate();
    const appwrite = useContext(AppwriteContext);

    const handleLogin = (e) => {
        e.preventDefault();
        appwrite.loginUser(email,password).then((res) =>{
            console.log("Logged In!", res);
            window.location = "/"
        }).catch((error) =>{
            console.log("Error logging in", error);
        })
        // console.log({ email : email, password : password});
    }

   return (
    <div className='Login'>
        <div className='Login-left'>
            <div className='login-home'>
                <img className='login-home-btn' onClick={()=>{
                    navigator("/");
                }} src={Pig} alt="pigshell"/>
            </div>
            <div className='Login-head'>
                <div>Log In</div>
                <div className='Login-subhead'>
                    Login to view your images
                </div>
            </div>
            <div className='Login-card'>
                <form className='Login-form'>
                    {/* <label for="name">Your Name</label> */}
                    <input className='Login-input' placeholder='Email' autoComplete='off' id='login-email' value={email} onChange={(e)=>{
                        setEmail(e.target.value);
                    }}/>
                    <input className='Login-input'  placeholder='Password' type='password' autoComplete='off' id='login-password' value={password} onChange={(e)=>{
                        setPassword(e.target.value);
                    }}/>
                    <button type="submit" onClick={handleLogin} id='login-btn'>Log In</button>
                </form>
            </div>
            <div className='Login-footer'>
                <p>Don't have account? <a className='login-redirect highlight-text' href='/signup'>Signup Here</a></p>
            </div>
        </div>
        <div className='Login-right'>
        <div className='Login-welcome'>
        <h2>Welcome Back</h2>
            <p>We were missing your Piggy Awesomeness!</p>
        </div>
        <div className='Login-img'>
            <img src={LoginImg} alt='login'/>
        </div>
        </div>
    </div>
  )
}

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

Посмотрите весь код здесь : Pigshell 🐷

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

Это будет доступно для использования очень скоро 😉😉😉.

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