Akce
React autentizace » Historie » Revize 15
« Předchozí |
Revize 15/17
(rozdíl)
| Další »
Jiří Trefil, 2023-04-23 10:17
Autentizace na straně klienta (React aplikace)¶
Popis logiky autentizace¶
- Uživatel se přihlásí pod svým účtem.
- Klientská aplikace pošle tento požadavek na SPADe aplikaci. Pokud je tento požadavek validní, tj. uživatel opravdu existuje a heslo je správné, pak je zpět odeslán JWT token (https://jwt.io/introduction).
- Klientská aplikace si tento token přečte a uloží jej do cookie. Tento token je od tohoto bodu posílán s každým klientským požadavkem na server v hlavičce, viz obrázek hlavičky níže.
- Pouze takto je uživatel považován za autentikováno a může se svobodně pohybovat po aplikaci bez omezení.
Knihovna react-auth-kit¶
- K implementaci této feature byla použita knihovna třetí strany. Knihovna spravuje celý stav autentizace na straně klienta.
- Po přihlášení uživatele tedy knihovna uloží jwt token do cookie a následně poskytne 3 hooky (konkrétně useState), které s tímto tokenem manipulují.
- Následuje ukázka kódu, která používá knihovnu pro přihlášení uživatele.
Přihlášení uživatele¶
Ukázka kódu představuje první hook: UseSignIn.
//importujeme useEffect knihovny pro prihlaseni uzivatele
import {useSignIn} from "react-auth-kit";
//komponenta pro prihlaseni uzivatele
const LoginComponent = () => {
//initneme funkci knihovny
//ktera udela vsechnu praci s ukladanim tokenu
const signIn = useSignIn();
//dummy funkce, ktera pouze demonstruje, jak se knihovna pouziva
//samotna implementace v kodu je v jadru stejna, pouze je kolem vice omacky
//pro tuto ukazku nedulezite
const sampleLogin = async (username:string, password: string) =>{
//V tomto bode zavolame server s nasim login pozadavkem
//odpoved serveru je ve formatu jako nasledujici rozepsany objekt
//tedy vratime nam status (HTTP code) - tim zjistime, jestli se neco nepokazilo
//zpravu (message) - pro blizsi informace o vysledku informace
//samotny jwt token (token) - timto tokenem se uzivatel autentikuje s kazdym nasledujicim pozadavkem na server
const responseWrapper: {message:string; status:number; token:string} = await login(username,password);
//token muze byt empty string, pokud doslo k chybe prihlaseni
const accessToken:string = responseWrapper.token;
if(responseWrapper.status != 200){
//Zde by byla cast, ktera by vypsala uzivateli chybovou hlasku, protoze se prihlaseni nepovedlo
}
//volame samotny useEffect pro ulozeni tokenu do cookie
signIn({
//token, ktery ukladame, v nasem pripade promenna accessToken
// cookie bude mit nazev "token"
token:accessToken,
//jak dlouho token zije (v minutach)
expiresIn: 3600,
//typ tokenu, v pripade JWT se jedna o Bearer token
tokenType: "Bearer",
// co dalsiho si chceme ulozit, napriklad jmeno uzivatele, nutne to tu byt nemusi
authState: {userName:username}
});
}
}
export default LoginComponent;
Kontrola, zda je uživatel autentikován¶
Tato ukázka kódu představuje druhý hook: useIsAuthenticated.
//naimportujeme si hook knihovny
import {useIsAuthenticated} from "react-auth-kit";
import React, {useEffect, useState} from 'react';
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import Container from 'react-bootstrap/Container';
//Komponenta reprezentuji navigacni menu pro uzivatele
const NavBar = () => {
//interni stav komponenty, ktera si drzi informace o tom, zda je uzivatel prihlasen
const [isAuthenticated,setAuthenticated] = useState(false);
//inicializujeme hook knihovny
const authenticated = useIsAuthenticated();
//useEffect hook komponenty
useEffect(()=>{
//pri kazde zmene stavu komponenty se dotazeme, zda je uzivatel autentikovan
//token totiz uz mohl vyprset nebo samozrejme vubec nemusi existovat (uzivatel se jeste ani neprihlasil)
//knihovna zde neudela nic vic, nez ze se podiva, jestli existuje cookie s nazvem "token", pokud existuje
//tak se podiva, zda token neni expirovany (opet ma ulozeno v cookie, pouze pod jinym klicem)
const isAuthed = authenticated();
//nastavime true/false podle toho, zda je uzivatel autentikovan, tj. ma platny a neexpirovany token
setAuthenticated(isAuthed);
})
return (
<Navbar bg="light" expand="lg">
<Container fluid>
<Navbar.Brand href="/">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav"/>
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Nav.Link href="/about">About</Nav.Link>
<Nav.Link href="/detect">Detect</Nav.Link>
<Nav.Link href="/configuration">Configuration</Nav.Link>
</Nav>
{
//Je uzivatel prihlasen?
//pokud je prihlasen, vykresli mu tlacitkou na odlhaseni
//pokud neni prihlasen, vykresli mu tlacitko na prilaseni
isAuthenticated?
<Nav.Link href="/logout">Logout</Nav.Link>
:
<Nav.Link href="/login">Sign in</Nav.Link>
}
</Navbar.Collapse>
</Container>
</Navbar>
);
};
export default NavBar;
Odhlášení uživatele¶
Tato ukázka představí poslední hook: useSignOut.
import React, { useEffect } from 'react';
//Naimportujeme si hooky. Nove tedy hook useSignOut, ktery vycisti cookies pri odhlaseni uzivatele
import {useSignOut,useIsAuthenticated} from "react-auth-kit";
import {logoutUser} from "../api/APILogout";
import {retrieveUsernameFromStorage,invalidateLocalStorage} from "../context/LocalStorageManager";
function Logout() {
//opet inicializujeme funkce knihovny
//tedy funkce, ktera se pta, zda je uzivatel autentikovan
const isAuthenticated = useIsAuthenticated();
// a funkce, ktera odhlasi uzivatele
const signOut = useSignOut();
useEffect(() => {
//vytahneme z local storage jmeno uzivatele, ktery se chce odhlasit
const userName: string = retrieveUsernameFromStorage();
//pokud je uzivatel autentikovany a zaroven znam jeho jmeno, tak jej odhlasim
if(isAuthenticated() && userName != null){
//zavolej server s requestem na odhlaseni, tedy znevalidneni tokenu
logoutUser(userName);
//smaz celou local storage uzivatele
invalidateLocalStorage();
//samotne volani hooku knihovny - smaze vsechny cookies, ve kterych byl ulozen token a informace k tokenu
signOut();
}
//presmerujeme uzivatele zpatky na root stranku aplikace
window.location.href = '/';
});
//vratime null, aby react router pochopil, ze se proklikem v navbaru vola tato funkce a nebude se vykreslovat komponenta
return null;
}
export default Logout;
Aktualizováno uživatelem Jiří Trefil před téměř 2 roky(ů) · 15 revizí