Sütik

Sütiket használunk a tartalom személyre szabására és a forgalom elemzésére. Kérjük, határozza meg, hogy hajlandó-e elfogadni weboldalunkon a sütiket.

Oldal tetejére
Bezárás
Zengo - Hogyan hozzunk létre React webalkalmazást a Laravel Sanctum segítségével - 2. rész: KIJELENTKEZÉS
2022. 05. 31.

Hogyan hozzunk létre React webalkalmazást a Laravel Sanctum segítségével - 2. rész: KIJELENTKEZÉS

Zengo - Olvasási idő2 perc Olvasási idő

Az előző fejezetben felépítettünk egy webalkalmazást, ahová bejelentkezhetünk és megvédhetjük az útvonalakat a nem hitelesített felhasználóktól.

Mielőtt új funkciókat adnánk hozzá az alkalmazásunkhoz, frissítenünk kell a felhasználói felületünket, mert az jelenleg kissé ingerszegény. De emiatt nem kell aggódnunk, mivel ehhez már remek eszközeink vannak. Korábban telepítettük a Material-UI könyvtárat, így most először is létrehozunk egy MainLayout komponenst. Ez foglalja keretbe a webalkalmazásunk tartalmát.

>>> resources/js/components/MainLayout/MainLayout.js
import React from "react";
import {Container} from "@mui/material";

function MainLayout({children}) {
    return (
        <Container>
            {children}
        </Container>
    )
}

export default MainLayout

Amint látjátok, az alkalmazás tartalma gyermekként kerül át az komponenshez. Ennek ellenére később átadhatunk weboldal- és oldalspecifikus paramétereket, például az oldal nevét, hogy milyen tartalmak jelenjenek meg a fejlécben (App Bar-ban) stb.

Most már használhatjuk ezt a komponenst a főoldal egységbe foglalásához:

>>> resources/js/components/Dashboard/Dashboard
import React from "react";
import user from "../../Models/user";
import {Grid, Typography} from "@mui/material";
import MainLayout from "../MainLayout/MainLayout";

function Dashboard() {
    return (
        <MainLayout>
            <Grid container justifyContent={"center"}>
                <Grid item>
                    <Typography variant={"h5"}>
                        Hello {user.name}, you're logged in!
                    </Typography>
                </Grid>
            </Grid>
        </MainLayout>
    )
}

export default Dashboard

Figyeljük meg, hogy nem kell használnunk a Container-t a Dashboard komponensben, mert a MainLayoutban már megtettük. A Dashboard komponensből adatokat is átadhatunk a MainLayoutnak, például az oldal címét:

{...}
<MainLayout title={"Dashboard"}>
{...}

Most már elérhetjük a title változót a wrapper komponensben. Vegyünk néhány változtatást a jobb megjelenés érdekében:

import React from "react";
import {
    AppBar,
    Paper,
    Container,
    Box,
    CssBaseline,
    Toolbar,
    Typography
} from "@mui/material";

function MainLayout({children, title}) {
    return (
        <React.Fragment>
            <CssBaseline/>
            <AppBar position={"static"}>
                <Toolbar>
                    <Typography
                        variant={"h6"}
                        component={"div"}
                        sx={{flexGrow: 1}}
                    >
                        {title} // Here is our passed data!
                    </Typography>
                </Toolbar>
            </AppBar>

            <Container>
                <Box
                    sx={{
                        marginTop: 8,
                        display: 'flex',
                        width: '100%',
                        height: '100%',
                        flexDirection: 'column',
                        alignItems: 'center',
                    }}
                >
                    <Paper sx={{
                        width: '100%',
                        padding: 2
                    }}>
                        {children}
                    </Paper>
                </Box>
            </Container>
        </React.Fragment>
    )
}

export default MainLayout

Most már valamennyivel szebb felületünk van. 100%

Érvénytelenítsük a sessiont

Session alapú hitelesítést használunk. Ellenkező esetben a Sanctum segítségével teljesen token alapú hitelesítést készíthetnénk. Azonban a jelenlegi megvalósításunkhoz, létrehozunk egy új metódust a LoginControllerben, úgynevezett logout-ot, amely érvényteleníti a hitelesített felhasználó aktuálisan használt munkamenetét (session-jét).

>>> app/Controllers/LoginController
/**
 * @param Request $request
 * @return JsonResponse
 */
public function logout(Request $request): JsonResponse
{

    $request->session()->invalidate();

    $request->session()->regenerateToken();

    return response()->json('Successfully logged out');
}

Az api útvonalak fájljában néhány változtatást eszközöltünk a jobb megjelenés érdekében. Először is csoportosítottuk útvonalainkat, melyek hitelesítést igényelnek, majd ezt követően meghatároztuk a kijelentkezési útvonalat.

>>> routes/api.php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\LoginController;

Route::post('login', [LoginController::class, 'authenticate']);

Route::group(['middleware' => 'auth:sanctum'], function (){
    Route::get('/user', function (Request $request) {
        return $request->user();    
    });

    Route::post('/logout', [LoginController::class, 'logout']);
});

Kijelentkezés a kliens oldalon

Amikor kijelentkezünk az alkalmazásunkból, szeretnénk megbizonyosodni arról, hogy minden felhasználóhoz kapcsolódó adat (amit a kliens oldalon tárolunk) törlődik. A user.js-ben új metódust hozunk létre a takarításhoz.

>>> resources/js/Models/user.js
{...}
/**
 * Remove all user's data from local storage
 */
destroy() {
    localStorage.removeItem('userName')
    localStorage.removeItem('userEmail')
    localStorage.removeItem('userLoggedIn')
}

/**
 *
 * @param callback function
 */
logout(callback) {
    this.destroy()

    callback()
}
{...}

Létrehozunk egy új Kijelentkezési gomb komponenst, ami elvégzi a feladatot:

>>> resources/js/components/MainLayout/LogoutButton/LogoutButton
import React from "react";
import {Button, Box} from "@mui/material";

function LogoutButton() {

    const logout = (e) => {
        e.preventDefault()
        //log out..
    }

    return (
        <React.Fragment>
            <Box component={"form"} onSubmit={logout}>
                <Button color={'inherit'} type={"submit"}>
                    Logout
                </Button>
            </Box>
        </React.Fragment>
    )
}

export default LogoutButton

Ezt a gombot hozzáadhatjuk a Dashboard title-je után:

>>> resources/js/components/MainLayout/MainLayout
{...}
<Toolbar>
    <Typography
        variant={"h6"}
        component={"div"}
        sx={{flexGrow: 1}}
    >
        {title}
    </Typography>
    <LogoutButton/>
</Toolbar>
{...}

Ezt követően megjelenik a gomb. Most megcsinálhatjuk a kijelentkezés logikáját:

import React from "react";
import {Button, Box} from "@mui/material";
import user from "../../../Models/user";
import {withRouter} from "react-router-dom";

function LogoutButton({history}) {

    const logout = (e) => {
        e.preventDefault()

        window.axios.post('/api/logout')
            .then(() => {
                //successful response
            })
            .catch(() => {
                //handle if something went wrong
            })
            .then(() => {
                //this code will be definitely executed
                user.logout(afterUserDestroyed)
            })
    }

    const afterUserDestroyed = () => {
        history.push('/app/login')
    }

    return (
        <React.Fragment>
            <Box component={"form"} onSubmit={logout}>
                <Button
                    type={"submit"}
                    color={'inherit'}
                >
                    Logout
                </Button>
            </Box>
        </React.Fragment>
    )
}

export default withRouter(LogoutButton)

Az axios "második” then() promise metódusát használtuk, mert az mindig végrehajtásra kerül. Ez egy egyszerű megoldás, ha fel akarjuk készíteni az alkalmazásunkat a szerver oldali hibákra, vagy bármilyen egyéb felmerülő problémára. Így biztosak lehetünk abban, hogy a felhasználó kijelentkezik a kliens oldalon. 100%

A projekt frissített Github könyvtárát itt megtaláljátok, ahol a működő kódhoz is hozzáfértek. Reméljük, hasznosnak tartottátok cikkünket! Hasonló szakmai írásokért olvassátok el további blogbejegyzéseinket!


A cikk eredeti változata elérhető itt. Fordította: Kádár Kyra