"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > MANIPULANDO AUTH EM APLICATIVOS REACT USANDO NANOSTORES E API DE CONTEXTO

MANIPULANDO AUTH EM APLICATIVOS REACT USANDO NANOSTORES E API DE CONTEXTO

Publicado em 2024-08-20
Navegar:918

HANDLING AUTH IN REACT APPS USING NANOSTORES AND CONTEXT API

Em meus dias de iniciante na construção de aplicativos web full stack com ReactJs, fiquei confuso sobre como lidar com a autenticação no frontend. Quero dizer, o que você deve fazer depois de receber seu token de acesso do backend? Como você preserva o estado de login?

A maioria dos iniciantes presumiria “Ah, basta armazenar seu token no estado”. Mas descobri rapidamente que não era a melhor solução, nem sequer é uma solução porque, como a maioria dos desenvolvedores experientes de ReactJs sabem, o estado é temporário porque é limpo cada vez que você atualiza a página e nós definitivamente podemos' não é possível fazer login do usuário sempre que ele é atualizado.

Avanço rápido, agora que ganhei um pouco de experiência na construção de aplicativos full stack em reação, estudando a abordagem de um desenvolvedor mais experiente para autenticação e replicando o processo em dois outros aplicativos, gostaria de dar um guia sobre como eu lido com isso atualmente. Algumas pessoas podem não pensar que é o melhor caminho, mas eu o adotei por enquanto e estou aberto a aprender outros métodos usados ​​por outros desenvolvedores.

PASSO UM

Você enviou seu e-mail e senha (supondo que esteja usando autenticação básica de e-mail e senha) ao back-end para iniciar o processo de autenticação. Não falarei sobre como a autenticação é tratada no back-end porque este artigo é sobre como lidar com a autenticação apenas no front-end. Vou pular para a parte em que você recebeu um token na resposta HTTP. Abaixo está um exemplo de código de um componente de formulário de login simples que envia o e-mail e a senha ao servidor e recebe o token e as informações do usuário na resposta. Agora, por uma questão de simplicidade, meus valores de formulário são gerenciados com estado, seria muito melhor usar uma biblioteca robusta como o formik para aplicativos de produção.

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)}/>
) }

PASSO DOIS

Envolva todo o seu aplicativo ou apenas as partes que precisam de acesso ao estado de autenticação em um provedor de contexto de autenticação. Isso geralmente é feito em seu arquivo App.jsx raiz. Se você não tem ideia do que é API de contexto, sinta-se à vontade para verificar a documentação do Reactjs. Os exemplos abaixo mostram um componente do provedor AuthContext criado. Em seguida, ele é importado em App.jsx e usado para agrupar o RouterProvider retornado no componente App, tornando o estado de autenticação acessível de qualquer lugar no aplicativo.

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

PASSO TRÊS

No contexto de autenticação, você deve inicializar duas variáveis ​​de estado, “isLoggedIn” e “authenticatedUser”. O primeiro estado é um tipo booleano que será inicialmente definido como ‘false’ e depois atualizado para ‘true’ assim que o login for confirmado. A segunda variável de estado é usada para armazenar as informações do usuário conectado, como nomes, e-mail, etc. Essas variáveis ​​de estado devem ser incluídas no valor do provedor retornado no componente de contexto para que possam ser acessíveis em todo o aplicativo para renderização condicional. .

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}
        
    )
}

PASSO QUATRO

Nanostores é um pacote para gerenciar estado em aplicativos Javascript. O pacote fornece uma API simples para gerenciar valores de estado em vários componentes, simplesmente inicializando-o em um arquivo separado e importando-o em qualquer componente onde você deseja usar o estado ou atualizá-lo. Mas, com a finalidade de armazenar seu token de autenticação recebido na resposta HTTP na etapa um, você usará nanostores/persistentes. Este pacote persiste em seu estado armazenando-o em localStorage, dessa forma ele não é apagado quando você atualiza a página. @nanostores/react é uma integração específica de reação para nanostores, disponibiliza o gancho useStore para extrair valores de um estado nanostore.

Então agora você pode ir em frente e:

  • Instale os seguintes pacotes: nanostores, @nanostores/persistent e @nanostores/react.

  • Em um arquivo separado chamado user.atom.js ou qualquer nome que você escolher, inicialize um armazenamento ‘authToken’ e um armazenamento ‘user’ usando nanostores/persistent.

  • Importe-os para o arquivo do componente do formulário de login e atualize o estado com o token e os dados do usuário recebidos em sua resposta de login.

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
        }
    }

PASSO CINCO

Agora, no contexto de autenticação que envolve seu aplicativo, você precisa garantir que o token e os estados do usuário sejam mantidos atualizados e disponibilizados em todo o aplicativo. Para conseguir isso, você deve:

  • Importe as lojas ‘authToken’ e ‘user’.

  • Inicialize um gancho useEffect, dentro do gancho, crie uma função 'checkLogin()' que irá verificar se o token está presente no armazenamento 'authToken', se estiver, execute uma função para verificar se está expirado. Com base nos resultados da verificação, você redireciona o usuário para a página de login para ser autenticado OU… define o estado ‘isLoggedIn’ como verdadeiro. Agora, para garantir que o estado de login seja rastreado com mais frequência, esse gancho pode ser configurado para ser executado sempre que o caminho atual mudar, dessa forma, um usuário pode ser expulso ou redirecionado para a página de login se seu token expirar durante a interação com o aplicativo .

  • Inicialize outro gancho useEffect que conterá uma função para buscar as informações do usuário do back-end usando o token no armazenamento authToken sempre que o aplicativo for carregado ou atualizado. Se você receber uma resposta bem-sucedida, defina o estado ‘isLoggedIn’ como verdadeiro e atualize o estado ‘authenticatedUser’ e o armazenamento ‘user’ com as informações do usuário recebidas na resposta.

Abaixo está o arquivo do componente AuthProvider atualizado.

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}
        
    )
}

CONCLUSÃO

Agora, esses dois ganchos useEffect criados na etapa cinco são responsáveis ​​por manter o estado de autenticação de todo o seu aplicativo gerenciado. Cada vez que você faz uma atualização, eles são executados para verificar seu token no armazenamento local, recuperar os dados mais atuais do usuário diretamente do back-end e atualizar seu estado ‘isLoggedIn’ e ‘authenticatedUser’. Você pode usar os estados dentro de qualquer componente importando o gancho ‘AuthContext’ e ‘useContext’ do react e chamando-os dentro do seu componente para acessar os valores e usá-los para alguma renderização condicional.

importar {useContext} de "react"; importar { AuthContext } de "./AuthContext"; função padrão de exportação MyLoggedInComponent() { const { isLoggedIn, authenticatedUser } = useContext(AuthContext) retornar( { está logado?

Bem-vindo {authenticatedUser?.name}

: Entrar } > ) }
import { useContext } from "react";
import { AuthContext } from "./AuthContext";

export default function MyLoggedInComponent() {

    const { isLoggedIn, authenticatedUser } = useContext(AuthContext)

    return(
        
        {
            isLoggedIn ? 
            

Welcome {authenticatedUser?.name}

: } > ) }
Lembre-se, ao sair, você deve limpar o armazenamento ‘authToken’ e ‘user’, definindo-os como nulos. Você também precisa definir ‘isLoggedIn’ como falso e ‘authenticatedUser’ como nulo.

Obrigado pela leitura!

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/ikemcodedit/handling-auth-in-react-apps-using-nanostores-and-context-api-35kg?1 Se houver alguma violação, entre em contato com study_golang@163 .com para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3