Soukromé trasy Sveltekit s backendless

Pokud jste sledovali spolu s předchozími články, měli byste mít funkční stránku Přihlášení a registrace připojenou k Backendless. Nyní je trochu zefektivníme a přidáme soukromé směrování přes SvelteKit.

Na domovské stránce jsme moc práce neudělali (index.svelte ), takže na tom teď zapracujeme. Odstraňte výchozí kód Svelte a přidejte nějaký základní obsah. Nejprve přidáme HTML a poté přidáme novou stránku s názvem members.svelte

index.svelte

<script>
    import {user} from "$lib/store";
</script>

<div class="container mx-auto">
    <h1 class="text-5xl font-bold mb-3">Hello World</h1>
    <p>
        <a href={$user.email ? "/members" : "/login"} class="btn btn-outline">
            Click here for the private route
        </a>
    </p>
</div>

Uvidíte, že náš odkaz href je zabaleno do if tvrzení. Každá z vašich soukromých tras by měla být napsána takto, abyste se ujistili, že je uživatel přihlášen. Případně můžete celou značku odkazu zabalit do Svelte {#if}{/if} Pokud chcete tlačítko úplně skrýt. Kdykoli ve svém obsahu HTML použijete obchod Svelte Store, musíte použít reaktivní symbol $ . Obsah tak bude vědět, že se tato proměnná změní, a bude sledovat aktualizace.

Můžete to také použít k připojení cílové trasy k přihlašovací stránce, například /login?target-route=members a poté přesměrovat uživatele po přihlášení, ale to bude v jiném tutoriálu.

Vytvořte stránku členů

Nyní vytvořte novou stránku v routes složku s názvem members.svelte a přidejte k tomu také nějaký základní html.

members.svelte

<div class="container mx-auto">
    <h1 class="text-5xl font-bold mb-3">Members Only!</h1>
    <p><a href="/" class="btn btn-outline">Return Home</a></p>
</div>

Na této stránce nepotřebujeme zacházet s kotevními značkami efektními if prohlášení, protože web to uvidí jako soukromou cestu a zcela ji skryje neověřeným uživatelům.

Vytvoření systému soukromé trasy

S Backendless, když se přihlásíte, je vrácen objekt obsahující některé vaše uživatelské informace. V našem login.svelte aktualizujeme náš globální obchod Svelte Store user být tato hodnota. Protože je to nyní globální, můžeme to použít na našem __layout.svelte soubor zkontrolovat vždy, když někdo prochází webem. Pokud se dostanou na soukromou stránku a nejsou přihlášeni, elegantně je přesměrujeme zpět na přihlašovací obrazovku.

Toho dosáhneme vytvořením seznamu adres URL, které bychom měli zkontrolovat.

Vytvoření seznamu adres URL

Uvnitř vašeho lib/data vytvořte nový soubor s názvem publicRoutes.json . Uvnitř bude pole obsahující tři stránky pro začátek. Domovská stránka, přihlašovací stránka a registrační stránka. Pokud se neověřený uživatel dostane na stránku, která NENÍ v tomto seznamu, bude přesměrován na přihlašovací stránku.

publicRoutes.json

[
    "/",
    "/login",
    "/register"
]

Všechny budoucí veřejné trasy, jako je příspěvek na blogu nebo stránka Kontaktujte nás, budou uvedeny zde v tomto seznamu.

Ověření uživatele

Uvnitř vašeho lib/functions vytvořte nový soubor s názvem auth.js . To pro nás bude mít v budoucnu několik funkcí. Prozatím chceme vytvořit novou funkci nazvanou validateUserToken . Tato funkce zkontroluje Backendless token, který je uložen ve vašem localStorage, a ujistí se, že nevypršela jeho platnost nebo že s ním nebylo manipulováno.

Než začneme, budeme muset naimportovat pár věcí. Váš počáteční soubor by měl vypadat nějak takto (s několika poznámkami):

auth.js

import Backendless from "backendless";
import {user} from "$lib/store";
import publicRoutes from "$lib/data/publicRoutes.json";
import {goto} from "$app/navigation";

// Check if user is logged in
export const validateUserToken = async() => {
    // Validate the user token

    // If valid: Update the user store with the latest information

    // If not valid: Unset the user store, and redirect to the login page

    // If the token is corrupted, force logout and redirect user to the login page
}

Poslední příkaz importu je nový pro výukový program. goto funkce je z knihovny Svelte a je snadným způsobem, jak automaticky nasměrovat uživatele na jinou stránku. To je to, co budeme používat k odesílání neověřených uživatelů na naši přihlašovací stránku.

Všimněte si, že jsme toto volání provedli jako asynchronní. Potřebujeme to k dokončení zpracování před směrováním našeho uživatele po celém webu. Pro začátek vytvoříme Try/Catch a přidáme naši první Backendless metodu pro kontrolu tokenu:

auth.js

export const validateUserToken = async() => {
    try {
        let response = await Backendless.UserService.getCurrentUser();
    } catch(error) {

    }
}

Do metody getCurrentUser() nemusíte nic předávat. Backendless SDK již ví, kde hledat token. To by mohlo vrátit objekt obsahující uživatelská data, null hodnotu, pokud uživatel není přihlášen, nebo kód chyby HTTP, pokud platnost tokenu vypršela nebo je poškozen.

auth.js

export const validateUserToken = async() => {
    try {
        let response = await Backendless.UserService.getCurrentUser();

        if(response) {
            // Valid user found
            user.set(response);
        } else {
            // Unset the user store
            user.set({});
        }
    } catch(error) {

    }
}

Nyní k přesměrování uživatele, pokud není přihlášen:

auth.js

export const validateUserToken = async() => {
    try {
        let response = await Backendless.UserService.getCurrentUser();

        if(response) {
            // Valid user found
            user.set(response);
        } else {
            // Unset the user store
            user.set({});

            // Invalid user found. Grab their current location to match against the publicRoutes list
            let currentLocation = window.location.pathname;

            // This will redirect if the unauthenticated user is on a private route
            if(!publicRoutes.includes(currentLocation)) {
                await goto("/login?error=expired-token");
                return false;
            }
        }
    } catch(error) {

    }
}

Toto používá jednoduchý includes abyste zjistili, zda je uživatel na soukromé trase. Pokud ano, pošlete je jinam. V tomto příkladu připojujeme parametr dotazu, abychom mohli na přihlašovací stránce zobrazit panel upozornění, že platnost jejich tokenu vypršela, a abychom se mohli znovu přihlásit. return false; zabrání spuštění čehokoli jiného ve funkci.

Uděláme něco velmi podobného v catch část, s další metodou Backendless vynuceného odhlášení, aby se zajistilo, že všechna uživatelská data budou resetována. Bude to vypadat takto:

auth.js

export const validateUserToken = async() => {
    try {
        let response = await Backendless.UserService.getCurrentUser();

        if(response) {
            // Valid user found
            user.set(response);
        } else {
            // Unset the user store
            user.set({});

            // Invalid user found. Grab their current location to match against the publicRoutes list
            let currentLocation = window.location.pathname;

            // This will redirect if the unauthenticated user is on a private route
            if(!publicRoutes.includes(currentLocation)) {
                await goto("/login?error=expired-token");
                return false;
            }
        }
    } catch(error) {
        // User has invalid token, so log them out
        await Backendless.UserService.logout();
        await goto("/?error=expired-token");
        return false;
    }
}

Pro konkrétní potřeby vašeho webu catch sekce může být užitečná pro přihlášení k externímu analytickému nástroji, když je token uživatele poškozen nebo mu vypršela platnost.

Přidání kontroly ověření do souboru rozvržení

Uvnitř __layouts.svelte musíme importovat funkci Svelte onMount , protože budeme muset ověřit token Backendless uložený v místním úložišti uživatele, když se uživatel přihlásí. Vzhledem k tomu, že Svelte je kompilovaný jazyk, kontrola všeho, co souvisí s prohlížečem, by měla být vždy uvnitř onMount nebo uvnitř volání funkce.

__layout.svelte

import {onMount} from 'svelte';

Protože se chceme ujistit, že každá trasa je před načtením zkontrolována, chceme, aby naše onMount být asynchronní, takže můžeme použít await vlastnictví. Spusťte onMount zavolejte takto:

__layout.svelte

onMount(async() => {
    // Code coming soon
}

Importujte náš nový validateUserToken a přidejte jej do onMount() zavolejte:

__layout.svelte

import {validateUserToken} from "$lib/functions/auth";

onMount(async() => {
    await validateUserToken();
})

Chcete-li vidět, jak to nyní funguje, ujistěte se, že jste odhlášeni ze svého backendless účtu tím, že vymažete své localStorage a ručně přejdete na /members trasa. Pokud bylo vše úspěšně nastaveno, měli byste být přesměrováni přímo na přihlašovací stránku.

Možná jste však viděli záblesk obsahu a to je to, co příště napravíme.

Poznámka:Tato další část je volitelná. Pokud vám blikání obsahu nevadí, můžete tento další krok přeskočit

Omezení obsahu

Stále v __layouts.svelte vytvořte novou proměnnou nad onMount jménem:

__layout.svelte

let isSiteReadyToLoad = false;

A v našem obsahu zabalíme veškerý obsah do if prohlášení to skrýt. To nám také dává možnost přidat pěknou animaci Svelte, aby se obsah rozplynul.

Můžete také přidat else zde a přidejte ikonu načítání, pokud ji máte.

Váš HTML by měl nyní vypadat nějak takto:

__layout.svelte

{#if isSiteReadyToLoad}
    {#if $user.email}
        <h1>Welcome, User</h1>
    {:else}
        <h1>Please login</h1>
    {/if}

    <slot></slot>
{/if}

Volitelný efekt animace

A chcete-li přidat animaci Svelte, importujte fade funkce v horní části vašeho <script> tag

__layout.svelte

import { fade } from 'svelte/transition';

K animaci prvku v Svelte potřebujete dvě věci:

  • Podmíněné (například naše isSiteReadyToLoad )
  • Standardní značka HTML, jako je <div> . Vlastnosti Svelte animace nefungují na Svelte Components.

Vaše HTML by mělo být strukturováno takto:

__layout.svelte

{#if isSiteReadyToLoad}
    <div transition:fade>
        {#if $user.email}
            <h1>Welcome, User</h1>
        {:else}
            <h1>Please login</h1>
        {/if}

        <slot></slot>
    </div>
{/if}

Abychom dokončili sekci Omezený obsah, můžeme nastavit hodnotu našeho isSiteReadyToLoad na hodnotu true za validateUserToken() funkce byla dokončena:

__layout.svelte

// Hide the site content until it is fully loaded
let isSiteReadyToLoad = false;

onMount(async() => {
    await validateUserToken();

    // Load the site
    isSiteReadyToLoad = true;
})

Nyní, pokud ručně přejděte na /members měla by na přihlašovací stránce zmizet a obsah členů už nikdy neuvidíte.

Chcete-li plně otestovat naši novou soukromou cestu, přihlaste se na stránku pomocí uživatelského jména a hesla, které jsme vytvořili zpět v kurzu #1. Jakmile jste přihlášeni, měli byste vidět své "Vítejte, uživatel" v levé horní části obrazovky. Nyní ručně přejděte na domovskou stránku a klikněte na tlačítko Členové.