Heim > Web-Frontend > js-Tutorial > Hauptteil

HANDHABUNG DER AUTH IN REACT-APPS UNTER VERWENDUNG VON NANOSTORES UND CONTEXT-API

王林
Freigeben: 2024-08-18 07:05:05
Original
966 Leute haben es durchsucht

HANDLING AUTH IN REACT APPS USING NANOSTORES AND CONTEXT API

In meinen Anfängertagen beim Erstellen von Full-Stack-Webanwendungen mit ReactJs war ich verwirrt darüber, wie ich mit der Authentifizierung im Frontend umgehen sollte. Ich meine, was sollten Sie als Nächstes tun, nachdem Sie Ihr Zugriffstoken vom Backend erhalten haben? Wie behalten Sie den Anmeldestatus bei?

Die meisten Anfänger würden annehmen: „Oh, bewahren Sie Ihren Token einfach im Status auf.“ Aber ich habe schnell herausgefunden, dass es weder die beste Lösung noch überhaupt eine Lösung ist, denn wie die meisten erfahrenen ReactJs-Entwickler wissen, ist der Status temporär, da er jedes Mal gelöscht wird, wenn Sie die Seite aktualisieren, und wir können es auf jeden Fall tun. Der Benutzer muss sich nicht bei jeder Aktualisierung anmelden.

Jetzt, wo ich ein wenig Erfahrung beim Erstellen von Full-Stack-Apps in React gesammelt habe, den Authentifizierungsansatz eines erfahreneren Entwicklers studiert und den Prozess in zwei anderen Anwendungen reproduziert habe, möchte ich einen Leitfaden geben darüber, wie ich derzeit damit umgehe. Manche Leute denken vielleicht nicht, dass es der beste Weg ist, aber ich habe es vorerst als meinen Weg übernommen und bin offen dafür, andere Methoden zu erlernen, die von anderen Entwicklern verwendet werden.

SCHRITT EINS

Sie haben Ihre E-Mail-Adresse und Ihr Passwort (vorausgesetzt, Sie verwenden die einfache E-Mail- und Passwort-Authentifizierung) an das Backend übermittelt, um den Authentifizierungsprozess zu starten. Ich werde nicht darüber sprechen, wie die Authentifizierung im Backend gehandhabt wird, da es in diesem Artikel ausschließlich darum geht, wie die Authentifizierung im Frontend gehandhabt wird. Ich gehe zu dem Teil über, in dem Sie in der HTTP-Antwort ein Token erhalten haben. Unten finden Sie ein Codebeispiel für eine einfache Anmeldeformularkomponente, die die E-Mail-Adresse und das Kennwort an den Server sendet und in der Antwort das Token und die Benutzerinformationen empfängt. Der Einfachheit halber werden meine Formularwerte jetzt mit dem Status verwaltet. Es wäre viel besser, eine robuste Bibliothek wie formik für Produktionsanwendungen zu verwenden.

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(
        <form onSubmit={handleSubmit}>
            <div>
                <input name="email" onChange={(e) => setEmail(e.target.value)}/>
                <input name="password" onChange={(e) => setPassword(e.target.value)}/>
            </div>
            <div>
                <button type="submit">
                    Login
                </button>
            </div>
        </form>
    )
}
Nach dem Login kopieren

SCHRITT ZWEI

Verpacken Sie Ihre gesamte Anwendung oder nur die Teile, die Zugriff auf den Authentifizierungsstatus benötigen, in einen Authentifizierungskontextanbieter. Dies erfolgt üblicherweise in Ihrer Root-App.jsx-Datei. Wenn Sie keine Ahnung haben, was eine Kontext-API ist, schauen Sie sich gerne die Reactjs-Dokumente an. Die folgenden Beispiele zeigen die erstellte AuthContext-Anbieterkomponente. Anschließend wird es in App.jsx importiert und zum Umschließen des in der App-Komponente zurückgegebenen RouterProviders verwendet, wodurch der Authentifizierungsstatus von überall in der Anwendung zugänglich gemacht wird.

import { createContext } from "react";

export const AuthContext = createContext(null)

export default function AuthProvider({children}) {

    return(
        <AuthContext.Provider>
            {children}
        </AuthContext.Provider>
    )
}
Nach dem Login kopieren
import React from "react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import AuthProvider from "./AuthContext";

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

function App() {
    return(
        <AuthProvider>
            <RouterProvider router={router} />
        </AuthProvider>
    )
}

export default App
Nach dem Login kopieren

SCHRITT DREI

Im Authentifizierungskontext müssen Sie zwei Statusvariablen initialisieren: „isLoggedIn“ und „authenticatedUser“. Der erste Status ist ein boolescher Typ, der zunächst auf „false“ gesetzt und dann nach Bestätigung der Anmeldung auf „true“ aktualisiert wird. Die zweite Statusvariable wird zum Speichern der Informationen des angemeldeten Benutzers wie Namen, E-Mail-Adresse usw. verwendet. Diese Statusvariablen müssen in den Wert für den Anbieter einbezogen werden, der in der Kontextkomponente zurückgegeben wird, damit in der gesamten Anwendung für bedingtes Rendering auf sie zugegriffen werden kann .

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(
        <AuthContext.Provider value={values}>
            {children}
        </AuthContext.Provider>
    )
}
Nach dem Login kopieren

SCHRITT VIER

Nanostores ist ein Paket zur Statusverwaltung in Javascript-Apps. Das Paket bietet eine einfache API zum Verwalten von Zustandswerten über mehrere Komponenten hinweg, indem es einfach in einer separaten Datei initialisiert und in jede Komponente importiert wird, in der Sie den Zustand nutzen oder aktualisieren möchten. Zum Speichern Ihres Authentifizierungstokens, das Sie in Schritt 1 in der HTTP-Antwort erhalten haben, verwenden Sie jedoch nanostores/persistent. Dieses Paket behält Ihren Status bei, indem es ihn in localStorage speichert, sodass er nicht gelöscht wird, wenn Sie die Seite aktualisieren. @nanostores/react ist eine reaktionsspezifische Integration für Nanostores. Sie stellt den useStore-Hook zum Extrahieren von Werten aus einem Nanostore-Status zur Verfügung.

Jetzt können Sie also weitermachen und:

  • Installieren Sie die folgenden Pakete: nanostores, @nanostores/persistent und @nanostores/react.

  • In einer separaten Datei namens user.atom.js oder wie auch immer Sie sie nennen möchten, initialisieren Sie einen „authToken“-Speicher und einen „user“-Speicher mit nanostores/persistent.

  • Importieren Sie sie in die Komponentendatei Ihres Anmeldeformulars und aktualisieren Sie den Status mit dem Token und den Benutzerdaten, die Sie in Ihrer Anmeldeantwort erhalten haben.

npm i nanostores @nanostores/persistent @nanostores/react
Nach dem Login kopieren
import { persistentMap } from '@nanostores/persistent'

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

export const user = persistentMap('user', null)
Nach dem Login kopieren
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
        }
    }
Nach dem Login kopieren

SCHRITT FÜNF

Jetzt müssen Sie in Ihrem Authentifizierungskontext, der Ihre App umschließt, sicherstellen, dass die Token- und Benutzerzustände auf dem neuesten Stand gehalten und in Ihrer gesamten App verfügbar gemacht werden. Um dies zu erreichen, müssen Sie:

  • Importieren Sie die Stores „authToken“ und „user“.

  • Initialie a useEffect hook, inside of the hook, create a ‘checkLogin()’ function which will check whether the token is present in the ‘authToken’ store, if it is, run a function to check whether it’s expired. Based on your results from checking, you either redirect the user to the login page to get authenticated OR… set the ‘isLoggedIn’ state to true. Now to make sure the login state is tracked more frequently, this hook can be set to run every time the current path changes, this way, a user can get kicked out or redirected to the login page if their token expires while interacting with the app.

  • Initialize another useEffect hook which will contain a function for fetching the user information from the backend using the token in the authToken store every time the app is loaded or refreshed. If you receive a successful response, set the ‘isLoggedIn’ state to true and update the ‘authenticatedUser’ state and the ‘user’ store with the user info received in the response.

Below is the updated AuthProvider component file.

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(
        <AuthContext.Provider value={values}>
            {children}
        </AuthContext.Provider>
    )
}

Nach dem Login kopieren

CONCLUSION

Now these two useEffect hooks created in step five are responsible for keeping your entire app’s auth state managed. Every time you do a refresh, they run to check your token in local storage, retrieve the most current user data straight from the backend and update your ‘isLoggedIn’ and ‘authenticatedUser’ state. You can use the states within any component by importing the ‘AuthContext’ and the ‘useContext’ hook from react and calling them within your component to access the values and use them for some conditional rendering.

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

export default function MyLoggedInComponent() {

    const { isLoggedIn, authenticatedUser } = useContext(AuthContext)

    return(
        <>
        {
            isLoggedIn ? 
            <p>Welcome {authenticatedUser?.name}</p>
            :
            <button>Login</button>
        }
        </>
    )
}
Nach dem Login kopieren

Remember on logout, you have to clear the ‘authToken’ and ‘user’ store by setting them to null. You also need to set ‘isLoggedIn’ to false and ‘authenticatedUser’ to null.

Thanks for reading!

Das obige ist der detaillierte Inhalt vonHANDHABUNG DER AUTH IN REACT-APPS UNTER VERWENDUNG VON NANOSTORES UND CONTEXT-API. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!