«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > ОБРАБОТКА АВТОРИЗАЦИИ В ПРИЛОЖЕНИЯХ REACT С ИСПОЛЬЗОВАНИЕМ NANOSTORES И CONTEXT API

ОБРАБОТКА АВТОРИЗАЦИИ В ПРИЛОЖЕНИЯХ REACT С ИСПОЛЬЗОВАНИЕМ NANOSTORES И CONTEXT API

Опубликовано 20 августа 2024 г.
Просматривать:772

HANDLING AUTH IN REACT APPS USING NANOSTORES AND CONTEXT API

Когда я только начинал создавать полнофункциональные веб-приложения с помощью ReactJ, я не понимал, как обрабатывать аутентификацию во внешнем интерфейсе. Я имею в виду, что вам следует делать дальше после получения токена доступа от серверной части? Как сохранить состояние входа?

Большинство новичков предполагают: «О, просто сохраните свой токен в состоянии». Но я быстро понял, что это не лучшее решение, и даже не решение вообще, потому что, как знают большинство опытных разработчиков ReactJ, состояние является временным, потому что оно очищается каждый раз, когда вы обновляете страницу, и мы определенно можем это сделать». у меня нет необходимости входить в систему каждый раз при обновлении.

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

ШАГ ПЕРВЫЙ

Вы отправили свой адрес электронной почты и пароль (при условии, что вы используете базовую аутентификацию по электронной почте и паролю) на серверную часть, чтобы начать процесс аутентификации. Я не буду говорить о том, как аутентификация обрабатывается во внутренней части, потому что эта статья посвящена тому, как обрабатывать аутентификацию исключительно во внешнем интерфейсе. Я перейду к той части, где вы получили токен в ответе HTTP. Ниже приведен пример кода простого компонента формы входа, который отправляет адрес электронной почты и пароль на сервер и получает в ответ токен и информацию о пользователе. Теперь, для простоты, значения моей формы управляются с помощью состояния, было бы гораздо лучше использовать надежную библиотеку, такую ​​как formik, для производственных приложений.

import axios from 'axios'
import { useState } from "react"

export default function LoginForm() {
    const [email, setEmail] = useState("")
    const [password, setPassword] = useState("")

    const handleSubmit = async() => {
        try {
            const response = await axios.post("/api/auth/login", { email, password })
            if (response?.status !== 200) {
                throw new Error("Failed login")
            }
            const token = response?.data?.token
            const userInfo = response?.data?.userInfo
        } catch (error) {
            throw error
        }
    }

    return(
        
setEmail(e.target.value)}/> setPassword(e.target.value)}/>
) }

ШАГ ВТОРОЙ

Оберните все приложение или только те его части, которым требуется доступ к состоянию аутентификации, в поставщике контекста аутентификации. Обычно это делается в корневом файле App.jsx. Если вы понятия не имеете, что такое контекстный API, ознакомьтесь с документацией Reactjs. В примерах ниже показан созданный компонент поставщика AuthContext. Затем он импортируется в App.jsx и используется для упаковки RouterProvider, возвращаемого в компоненте App, тем самым делая состояние аутентификации доступным из любой точки приложения.

import { createContext } from "react";

export const AuthContext = createContext(null)

export default function AuthProvider({children}) {

    return(
        
            {children}
        
    )
}
import React from "react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import AuthProvider from "./AuthContext";

const router = createBrowserRouter([
    // your routes here
])

function App() {
    return(
        
    )
}

export default App

ШАГ ТРЕТИЙ

В контексте аутентификации вам необходимо инициализировать две переменные состояния: «isLoggedIn» и «authenticatedUser». Первое состояние представляет собой логический тип, которому первоначально будет присвоено значение «false», а затем обновлено до «true» после подтверждения входа в систему. Вторая переменная состояния используется для хранения информации о вошедшем в систему пользователе, такой как имена, адрес электронной почты и т. д. Эти переменные состояния должны быть включены в значение для провайдера, возвращаемое в компоненте контекста, чтобы они могли быть доступны во всем приложении для условного рендеринга. .

import { createContext, useState } from "react";

export const AuthContext = createContext(null)

export default function AuthProvider({children}) {
    const [isLoggedIn, setIsLoggedIn] = useState(false)
    const [authenticatedUser, setAuthenticatedUser] = useState(null)

    const values = {
        isLoggedIn,
        authenticatedUser,
        setAuthenticatedUser
    }

    return(
        
            {children}
        
    )
}

ШАГ ЧЕТВЕРТЫЙ

Nanostores — это пакет для управления состоянием в приложениях Javascript. Пакет предоставляет простой API для управления значениями состояния в нескольких компонентах путем простой инициализации его в отдельном файле и импорта в любой компонент, где вы хотите использовать состояние или обновить его. Но для хранения вашего токена авторизации, полученного в ответе HTTP на первом этапе, вы будете использовать nanostores/persistent. Этот пакет сохраняет ваше состояние, сохраняя его в localStorage, поэтому оно не очищается при обновлении страницы. @nanostores/react — это специальная интеграция для наносторов, которая делает доступным хук useStore для извлечения значений из состояния наностора.

Итак, теперь вы можете идти дальше и:

  • Установите следующие пакеты: nanostores, @nanostores/persistent и @nanostores/react.

  • В отдельном файле с именем user.atom.js или любым другим именем по вашему выбору инициализируйте хранилище authToken и хранилище user, используя nanostores/persistent.

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

npm i nanostores @nanostores/persistent @nanostores/react
import { persistentMap } from '@nanostores/persistent'

export const authToken = persistentMap('token', null)

export const user = persistentMap('user', null)
import { authToken, user } from './user.atom'

 const handleSubmit = async() => {
        try {
            const response = await axios.post("/api/auth/login", { email, password })
            if (response?.status !== 200) {
                throw new Error("Failed login")
            }
            const token = response?.data?.token
            const userInfo = response?.data?.userInfo

            authToken.set(token)
            user.set(userInfo)
        } catch (error) {
            throw error
        }
    }

ШАГ ПЯТЫЙ

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

  • Импортируйте хранилища authToken и user.

  • Первоначально перехватчик useEffect, внутри перехватчика, создайте функцию «checkLogin()», которая будет проверять, присутствует ли токен в хранилище «authToken». Если да, запустите функцию, чтобы проверить, присутствует ли он истекший. Основываясь на результатах проверки, вы либо перенаправляете пользователя на страницу входа для аутентификации, ИЛИ… устанавливаете для состояния isLoggedIn значение true. Теперь, чтобы обеспечить более частое отслеживание состояния входа в систему, этот хук можно настроить на запуск каждый раз, когда изменяется текущий путь. Таким образом, пользователь может быть исключен или перенаправлен на страницу входа, если срок действия его токена истечет во время взаимодействия с приложением. .

  • Инициализируйте еще один хук useEffect, который будет содержать функцию для получения информации о пользователе из серверной части с использованием токена в хранилище authToken каждый раз, когда приложение загружается или обновляется. Если вы получили успешный ответ, установите для состояния isLoggedIn значение true и обновите состояние authenticatedUser и хранилище user информацией о пользователе, полученной в ответе.

Ниже приведен обновленный файл компонента AuthProvider.

import { createContext, useState } from "react";
import { authToken, user } from './user.atom';
import { useStore } from "@nanostores/react";
import { useNavigate, useLocation } from "react-router-dom";
import axios from "axios";

export const AuthContext = createContext(null)

export default function AuthProvider({children}) {
    const [isLoggedIn, setIsLoggedIn] = useState(false)
    const [authenticatedUser, setAuthenticatedUser] = useState(null)
    const token = useStore(authToken)
    const navigate = useNavigate()
    const { pathname } = useLocation()

    function isTokenExpired() {
        // verify token expiration and return true or false
    }

    // Hook to check if user is logged in 
    useEffect(() => {
        async function checkLogin () {
            if (token) {

              const expiredToken = isTokenExpired(token);

              if (expiredToken) {
                // clear out expired token and user from store and navigate to login page
                authToken.set(null)
                user.set(null)
                setIsLoggedIn(false);
                navigate("/login");
                return;
              }
            }
        };

        checkLogin()
    }, [pathname])

    // Hook to fetch current user info and update state
    useEffect(() => {
        async function fetchUser() {
            const response = await axios.get("/api/auth/user", {
                headers: {
                    'Authorization': `Bearer ${token}`
                }
            })

            if(response?.status !== 200) {
                throw new Error("Failed to fetch user data")
            }

            setAuthenticatedUser(response?.data)
            setIsLoggedIn(true)
        }

        fetchUser()
    }, [])

    const values = {
        isLoggedIn,
        authenticatedUser,
        setAuthenticatedUser
    }

    return(
        
            {children}
        
    )
}

ЗАКЛЮЧЕНИЕ

Теперь эти два перехватчика useEffect, созданные на пятом шаге, отвечают за управление состоянием аутентификации всего вашего приложения. Каждый раз, когда вы выполняете обновление, они запускаются, чтобы проверить ваш токен в локальном хранилище, получить самые последние пользовательские данные прямо из серверной части и обновить ваши состояния «isLoggedIn» и «authenticatedUser». Вы можете использовать состояния внутри любого компонента, импортировав AuthContext и крючок useContext из реакции и вызвав их внутри вашего компонента для доступа к значениям и использования их для некоторого условного рендеринга.

import { useContext } from "react";
import { AuthContext } from "./AuthContext";

export default function MyLoggedInComponent() {

    const { isLoggedIn, authenticatedUser } = useContext(AuthContext)

    return(
        
        {
            isLoggedIn ? 
            

Welcome {authenticatedUser?.name}

: } > ) }

Помните, что при выходе из системы вам необходимо очистить хранилища «authToken» и «user», установив для них значение null. Вам также необходимо установить для isLoggedIn значение false и для authenticatedUser значение null.

Спасибо за чтение!

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/ikemcodedit/handling-auth-in-react-apps-using-nanostores-and-context-api-35kg?1 В случае нарушения прав обращайтесь по адресу Study_golang@163. .com, чтобы удалить его
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3