Remove pagebreaks for now, I plan adding text

This commit is contained in:
Marko Korhonen 2020-05-09 12:07:59 +03:00
parent 6fc4750cdc
commit d12d412a84
No known key found for this signature in database
GPG key ID: 911B85FBC6003FE5
3 changed files with 0 additions and 28 deletions

View file

@ -22,5 +22,3 @@ Palvelinpuolella tarkoitetaan ohjelman osaa, johon asiakaspuoli yhdistyy noutaak
Palvelinpuoleen viitataan usein myös rajapintana (eng. Application Programming Interface, API), sillä tämänkaltaisia HTTP-protokollalla ohjattavia ohjelmia voi käyttää myös muuallakin kuin asiakaspuolen web-ohjelmissa. Rajapinnat voivat myös yhdistyä toisiinsa internetin välityksellä ja näin jakaa tietoja eri palveluiden välillä. Palvelinpuoleen viitataan usein myös rajapintana (eng. Application Programming Interface, API), sillä tämänkaltaisia HTTP-protokollalla ohjattavia ohjelmia voi käyttää myös muuallakin kuin asiakaspuolen web-ohjelmissa. Rajapinnat voivat myös yhdistyä toisiinsa internetin välityksellä ja näin jakaa tietoja eri palveluiden välillä.
Rajapintojen yleistyessä on kehitetty standardeja, joiden mukaan rajapintoja voi rakentaa. Näin rajapinnoista tulee helpompia käyttää kaikille. Yksi näistä standardeista on Representational state transfer (REST) \cite{wiki:rest}, jota pyrin käyttämään tämän insinöörityön projektia ohjelmoidessa. Rajapintojen yleistyessä on kehitetty standardeja, joiden mukaan rajapintoja voi rakentaa. Näin rajapinnoista tulee helpompia käyttää kaikille. Yksi näistä standardeista on Representational state transfer (REST) \cite{wiki:rest}, jota pyrin käyttämään tämän insinöörityön projektia ohjelmoidessa.
\clearpage

View file

@ -11,8 +11,6 @@ Automaattiselle roskienkeruulle on aikaisemmin ollut vaihtoehtona vain manuaalin
Rustin yhtenä pääominaisuutena on mainostettu sen uudenlaista näkökulmaa muistinhallintaan: omistajuutta \cite{rust:ownership}. Siinä jokaisella arvolla on omistaja, ja kun omistaja menee näkyvyysalueen ulkopuolelle, niin menevät myös sen omistamat arvotkin, eli ne vapautetaan muistista. Arvojen omistajuutta voi siirtää joko pysyvästi tai väliaikaisesti lainaamalla. Rustin yhtenä pääominaisuutena on mainostettu sen uudenlaista näkökulmaa muistinhallintaan: omistajuutta \cite{rust:ownership}. Siinä jokaisella arvolla on omistaja, ja kun omistaja menee näkyvyysalueen ulkopuolelle, niin menevät myös sen omistamat arvotkin, eli ne vapautetaan muistista. Arvojen omistajuutta voi siirtää joko pysyvästi tai väliaikaisesti lainaamalla.
\clearpage
\begin{code} \begin{code}
\inputminted{Rust}{code/ownership.rs} \inputminted{Rust}{code/ownership.rs}
\captionof{listing}{Omistajuus Rustissa} \captionof{listing}{Omistajuus Rustissa}
@ -54,8 +52,6 @@ Niissä tapauksissa, joissa tyypille voi olla useita vaihtoehtoja, tai silloin j
Koodiesimerkissä \ref{code:rust:type-notation} valitsin arvolle ''age'' tyypin u8, koska se on pienin kokonaislukutyypeistä ja sen arvo voi olla välillä 0-255. Näin voi potentiaalisesti vähentää ohjelman muistin käyttöä. Lisäksi tyypeillä voi myös karkeasti rajata funktion parametrien arvojen vaihteluväliä. Esimerkiksi jos on kirjoittamassa funktiota, joka ottaa parametrina henkilön iän, u8 on hyvä valinta, koska ihmisen ikä ei voi olla negatiivinen ja yksikään ihminen tuskin elää yli 255 vuotta. Koodiesimerkissä \ref{code:rust:type-notation} valitsin arvolle ''age'' tyypin u8, koska se on pienin kokonaislukutyypeistä ja sen arvo voi olla välillä 0-255. Näin voi potentiaalisesti vähentää ohjelman muistin käyttöä. Lisäksi tyypeillä voi myös karkeasti rajata funktion parametrien arvojen vaihteluväliä. Esimerkiksi jos on kirjoittamassa funktiota, joka ottaa parametrina henkilön iän, u8 on hyvä valinta, koska ihmisen ikä ei voi olla negatiivinen ja yksikään ihminen tuskin elää yli 255 vuotta.
\clearpage
Edellä mainittu tyyppi u8 on niin kutsuttu etumerkitön kokonaisluku (eng. \textbf{u}nsigned integer). Etumerkillisissä kokonaisluvuissa (eng. signed integer) käytetään yksi bitti merkkaamaan sitä, onko luku positiivinen vai negatiivinen. Etumerkittömissä luvuissa tätä ei tehdä, joten luku voi olla hieman isompi kuin etumerkillinen luku, mutta se ei voi olla negatiivinen. Edellä mainittu tyyppi u8 on niin kutsuttu etumerkitön kokonaisluku (eng. \textbf{u}nsigned integer). Etumerkillisissä kokonaisluvuissa (eng. signed integer) käytetään yksi bitti merkkaamaan sitä, onko luku positiivinen vai negatiivinen. Etumerkittömissä luvuissa tätä ei tehdä, joten luku voi olla hieman isompi kuin etumerkillinen luku, mutta se ei voi olla negatiivinen.
\def\2^#1{\hbox to1.6em{$2^{#1}$\hss}} \def\2^#1{\hbox to1.6em{$2^{#1}$\hss}}
@ -109,8 +105,6 @@ Toisin kuin C- ja C++ -kielissä, Rustissa on oletuksena etumerkittömien kokona
\label{code:rust:integer-overflow} \label{code:rust:integer-overflow}
\end{code} \end{code}
\clearpage
\subsection{Muuttumaton data} \subsection{Muuttumaton data}
Rustissa kaikki arvot ovat oletuksena muuttumattomia (engl.\ immutable). Jos muuttumattoman datan sijasta tarvitsee muuttujia (engl. mutable), voi käyttää avainsanaa ''mut'', esimerkiksi \mintinline{Rust}{let mut name = "Marko"}. Myös lainaukset suoritetaan oletuksena muuttumattomasti ja muutettavan lainauksen voi tehdä samalla avainsanalla, esimerkiksi \mintinline{Rust}{say_hello(&mut name)} Rustissa kaikki arvot ovat oletuksena muuttumattomia (engl.\ immutable). Jos muuttumattoman datan sijasta tarvitsee muuttujia (engl. mutable), voi käyttää avainsanaa ''mut'', esimerkiksi \mintinline{Rust}{let mut name = "Marko"}. Myös lainaukset suoritetaan oletuksena muuttumattomasti ja muutettavan lainauksen voi tehdä samalla avainsanalla, esimerkiksi \mintinline{Rust}{say_hello(&mut name)}
@ -122,8 +116,6 @@ Rustia kehitettäessä on aina ollut tavoitteena luotettavuus. Tämä tarkoittaa
Myös Rustin kääntäjään on panostettu paljon, ja virheiden sattuessa se on todella hyvä työkalu ohjelmoijalle. Se alleviivaa ongelmakohdat ja selittää lyhyesti, mistä ongelma johtuu. Jossain tapauksissa kääntäjä jopa antaa pieniä koodin pätkiä, mistä voi olla apua ongelman ratkaisemisessa [koodiesimerkki \ref{code:rust:help}]. Myös Rustin kääntäjään on panostettu paljon, ja virheiden sattuessa se on todella hyvä työkalu ohjelmoijalle. Se alleviivaa ongelmakohdat ja selittää lyhyesti, mistä ongelma johtuu. Jossain tapauksissa kääntäjä jopa antaa pieniä koodin pätkiä, mistä voi olla apua ongelman ratkaisemisessa [koodiesimerkki \ref{code:rust:help}].
\clearpage
\begin{code} \begin{code}
\inputminted[linenos=false]{shell}{code/compiler-help} \inputminted[linenos=false]{shell}{code/compiler-help}
\captionof{listing}{Rustin kääntäjä auttaa unohtuneen importin lisäämisessä} \captionof{listing}{Rustin kääntäjä auttaa unohtuneen importin lisäämisessä}
@ -156,8 +148,6 @@ Yksi todella mielenkiintoinen ominaisuus Rustissa on makrot. Se on toiminnallisu
\label{code:rust:macro} \label{code:rust:macro}
\end{code} \end{code}
\clearpage
Makron sisällä suluissa olevat lauseet ovat verrattavissa Rustin ''match''-lauseeseen. Kun makron syöte vastaa jotakin näistä lauseista, hakasulkujen sisällä oleva koodi generoidaan. Makrossa käytetty ''println!()'' on myös itsessään makro, joka tulee Rustin ''std'' -kirjaston mukana. Makron sisällä suluissa olevat lauseet ovat verrattavissa Rustin ''match''-lauseeseen. Kun makron syöte vastaa jotakin näistä lauseista, hakasulkujen sisällä oleva koodi generoidaan. Makrossa käytetty ''println!()'' on myös itsessään makro, joka tulee Rustin ''std'' -kirjaston mukana.
\bigskip \bigskip
@ -179,8 +169,6 @@ Aloitin itsekin opiskelemaan Rustia vain hieman ennen tämän insinöörityön a
\label{sect:paketinhallinta} \label{sect:paketinhallinta}
Rustin paketinhallinta on toteutettu Cargo-nimisellä ohjelmalla. Sitä voi käyttää koko ohjelmiston elinkaaren ajan aina projektin luomisesta sen julkaisemiseen. Cargon käsittelemiä paketteja kutsutaan laatikoiksi (eng. crate), jotka julkaistaan crates.io \cite{rust:cratesio} pakettirekisterissä. Laatikot voivat myös olla riippuvaisia toisista laatikoista. Laatikon tiedot ja riippuvuudet määritetään Cargo.toml-tiedostossa [koodiesimerkki \ref{code:rust:cargo-toml}]. Rustin paketinhallinta on toteutettu Cargo-nimisellä ohjelmalla. Sitä voi käyttää koko ohjelmiston elinkaaren ajan aina projektin luomisesta sen julkaisemiseen. Cargon käsittelemiä paketteja kutsutaan laatikoiksi (eng. crate), jotka julkaistaan crates.io \cite{rust:cratesio} pakettirekisterissä. Laatikot voivat myös olla riippuvaisia toisista laatikoista. Laatikon tiedot ja riippuvuudet määritetään Cargo.toml-tiedostossa [koodiesimerkki \ref{code:rust:cargo-toml}].
\clearpage
\begin{code} \begin{code}
\inputminted{TOML}{code/Cargo.toml} \inputminted{TOML}{code/Cargo.toml}
\captionof{listing}{Projektin palvelinpuolen Cargo.toml} \captionof{listing}{Projektin palvelinpuolen Cargo.toml}
@ -194,8 +182,6 @@ WebAssembly \cite{webassembly:home} on kehitteillä oleva asiakaspuolen ohjelmoi
Kehittäjän ei ole tarkoitus kirjoittaa WebAssemblya itse, vaan käyttää työkaluja, joilla olemassa olevia ohjelmointikieliä voi kääntää WebAssemblyksi. Rust on tästä hyvä esimerkki, sillä WebAssembly on yksi sen kääntäjän natiiveista ''targeteista'', samalla tavalla kuin vaikka x86-prosessorit. Kehittäjän ei ole tarkoitus kirjoittaa WebAssemblya itse, vaan käyttää työkaluja, joilla olemassa olevia ohjelmointikieliä voi kääntää WebAssemblyksi. Rust on tästä hyvä esimerkki, sillä WebAssembly on yksi sen kääntäjän natiiveista ''targeteista'', samalla tavalla kuin vaikka x86-prosessorit.
\clearpage
WebAssembly on siis ensisijaisesti binääriformaatti, mutta sen voi muuntaa myös tekstiformaatiksi, jonka nimi on WebAssembly text \cite{webassembly:text}. WebAssembly text käyttää syntaksissaan S-lausekkeita \cite{s-expression}. Se on notaatio puurakenteiselle datalle, joka on kehitetty Lisp-ohjelmointikieltä varten, joten WebAssembly text muistuttaa syntaksiltaan hyvin paljon Lispiä. WebAssembly textiä käytetään tilanteissa, joissa ihmisen täytyy ymmärtää, mitä koodissa tapahtuu. Tätä hyödynnetään esimerkiksi WebAssemblyn sisäisessä kehityksessä ja web-ohjelmistojen debuggereissa. WebAssembly on siis ensisijaisesti binääriformaatti, mutta sen voi muuntaa myös tekstiformaatiksi, jonka nimi on WebAssembly text \cite{webassembly:text}. WebAssembly text käyttää syntaksissaan S-lausekkeita \cite{s-expression}. Se on notaatio puurakenteiselle datalle, joka on kehitetty Lisp-ohjelmointikieltä varten, joten WebAssembly text muistuttaa syntaksiltaan hyvin paljon Lispiä. WebAssembly textiä käytetään tilanteissa, joissa ihmisen täytyy ymmärtää, mitä koodissa tapahtuu. Tätä hyödynnetään esimerkiksi WebAssemblyn sisäisessä kehityksessä ja web-ohjelmistojen debuggereissa.
\bigskip \bigskip

View file

@ -4,8 +4,6 @@ Tein insinöörityön yhteydessä full-stack projektin, jossa sekä palvelin- et
\section{Kehitysympäristön asennus} \section{Kehitysympäristön asennus}
Rust-projektin aloittamiseksi kehittäjä tarvitsee koneelleen Rustin paketinhallintatyökalun, Cargon (katso luku \ref{sect:paketinhallinta}). Olen itse Linux-käyttäjä, joten sain asennettua Cargon Linux-jakeluni ohjelmavarastosta. Windows-käyttäjille suosittelen käyttämään Rustup-asennusohjelmaa. Lisää tietoa Rustin asentamisesta saa Rustin kotisivuilta \cite{rust:install}. Rust-projektin aloittamiseksi kehittäjä tarvitsee koneelleen Rustin paketinhallintatyökalun, Cargon (katso luku \ref{sect:paketinhallinta}). Olen itse Linux-käyttäjä, joten sain asennettua Cargon Linux-jakeluni ohjelmavarastosta. Windows-käyttäjille suosittelen käyttämään Rustup-asennusohjelmaa. Lisää tietoa Rustin asentamisesta saa Rustin kotisivuilta \cite{rust:install}.
\clearpage
Projektin saa initialisoitua komennolla \mintinline{shell}{cargo init projektinnimi}. Tämä komento luo hakemiston ''projektinnimi'', minkä sisällä on Cargon konfiguraatiotiedosto Cargo.toml, jossa voi määrittää projektin tiedot ja riippuvuudet. Projektin saa initialisoitua komennolla \mintinline{shell}{cargo init projektinnimi}. Tämä komento luo hakemiston ''projektinnimi'', minkä sisällä on Cargon konfiguraatiotiedosto Cargo.toml, jossa voi määrittää projektin tiedot ja riippuvuudet.
Lähdekoodi sijaitsee hakemistossa ''src''. Cargo kirjoittaa hakemistoon valmiiksi ''main.rs'' -tiedoston, jossa on ''Hello world!'' esimerkkikoodi. ''main.rs'' on aina Rust-ohjelman ensimmäiseksi suoritettava tiedosto, eli niin kutsuttu entrypoint. ''main.rs''-tiedoston sisällä pitää olla ''main()''-funktio, josta ohjelman suoritus alkaa. Projektin voi suorittaa komennolla \mintinline{shell}{cargo run}. Lähdekoodi sijaitsee hakemistossa ''src''. Cargo kirjoittaa hakemistoon valmiiksi ''main.rs'' -tiedoston, jossa on ''Hello world!'' esimerkkikoodi. ''main.rs'' on aina Rust-ohjelman ensimmäiseksi suoritettava tiedosto, eli niin kutsuttu entrypoint. ''main.rs''-tiedoston sisällä pitää olla ''main()''-funktio, josta ohjelman suoritus alkaa. Projektin voi suorittaa komennolla \mintinline{shell}{cargo run}.
@ -20,8 +18,6 @@ Palvelinpuolen kehykseksi valikoitui Actix web. Se on käytännössä vastine Ja
Actix web on puolestaan rakennettu hyödyntämällä Actix-sovelluskehystä, joka on rakennettu löyhästi actor-mallin pohjalta. Actor-malli \cite{wiki:actor} on Carl Hewittin vuonna 1973 luoma matemaattinen ja tietotekninen malli rinnakkaisajosta. Tämän ansiosta Actix web on hyvin suorituskykyinen ja helposti skaalautuva ratkaisu rajapintoja rakennettaessa. Actix web on puolestaan rakennettu hyödyntämällä Actix-sovelluskehystä, joka on rakennettu löyhästi actor-mallin pohjalta. Actor-malli \cite{wiki:actor} on Carl Hewittin vuonna 1973 luoma matemaattinen ja tietotekninen malli rinnakkaisajosta. Tämän ansiosta Actix web on hyvin suorituskykyinen ja helposti skaalautuva ratkaisu rajapintoja rakennettaessa.
\clearpage
Actix web on myös hyvin integroitu Rustin vahvaan tyypitykseen. Erityisen vaikuttavaa oli se, että esimerkiksi tietyn rajapinnan päätepisteen POST-pyyntöön pystyy määrittämään parametriksi tietyn rakenteen (eng. structure) [koodiesimerkki \ref{code:rust:registeruser}]. Actix web on myös hyvin integroitu Rustin vahvaan tyypitykseen. Erityisen vaikuttavaa oli se, että esimerkiksi tietyn rajapinnan päätepisteen POST-pyyntöön pystyy määrittämään parametriksi tietyn rakenteen (eng. structure) [koodiesimerkki \ref{code:rust:registeruser}].
\bigskip \bigskip
@ -44,8 +40,6 @@ Kun koodiesimerkin \ref{code:rust:registeruser} funktioon ''register'' saapuu ko
Palvelinpuolen initialisointi ja käynnistäminen löytyvät liitteestä \ref{appx:actix}. Palvelinpuolen initialisointi ja käynnistäminen löytyvät liitteestä \ref{appx:actix}.
\clearpage
\subsection{Todentaminen} \subsection{Todentaminen}
Actix webin modulaarisuus mahdollisti myös helposti tarvittavien väliohjelmistojen sisällyttämisen ohjelman toimintaan. Actix identity -paketista löytyi tarvittavat palikat, joilla sain lisättyä itse kirjoittamani käyttäjän todentamistoiminnallisuuden suojaamaan haluttuja reittejä. Actix webin modulaarisuus mahdollisti myös helposti tarvittavien väliohjelmistojen sisällyttämisen ohjelman toimintaan. Actix identity -paketista löytyi tarvittavat palikat, joilla sain lisättyä itse kirjoittamani käyttäjän todentamistoiminnallisuuden suojaamaan haluttuja reittejä.
@ -96,8 +90,6 @@ Projektin asiakaspuolen aloittaminen vaati aika paljon tutkimustyötä. Rust-koo
Valitsemani sovelluskehys tukee molempia kirjastoja, mutta päädyin kuitenkin valitsemaan stdweb:n. Suurimpana syynä oli projektin aloittamisen helppous, joka tehdään Cargon liitännäisellä cargo-web. Toisena syynä oli, että WebAssembly-ohjelman paketointi web\char`_sys:n kanssa on tätä kirjoittaessani riippuvainen NodeJS:stä, kun taas stdweb ei vaadi NodeJS:n asennusta kehittäjän koneelle ollenkaan. Valitsemani sovelluskehys tukee molempia kirjastoja, mutta päädyin kuitenkin valitsemaan stdweb:n. Suurimpana syynä oli projektin aloittamisen helppous, joka tehdään Cargon liitännäisellä cargo-web. Toisena syynä oli, että WebAssembly-ohjelman paketointi web\char`_sys:n kanssa on tätä kirjoittaessani riippuvainen NodeJS:stä, kun taas stdweb ei vaadi NodeJS:n asennusta kehittäjän koneelle ollenkaan.
\clearpage
WebAssembly-koodin suorittamiseksi selain tarvitsee pienen pätkän JavaScriptiä, joka tekee tarvittavat toimet WebAssembly-ohjelman käynnistämiseksi. Tämän koodin generoi puolestani cargo-web. Lisäksi JavaScriptin suorittamiseen tarvitaan yksi HTML-tiedosto. Tähän tiedostoon voi myös sisällyttää metadataa, kuten esimerkiksi sivuston otsikon, joka näkyy selaimen välilehdessä. Tähän tiedostoon linkitetään myös kaikki muu staattinen data, kuten tyylimääritykset. Nämä tiedostot laitoin käytännön mukaisesti static-nimiseen hakemistoon asiakaspuolen projektin juureen. Tämän hakemiston linkitin symbolisella linkillä palvelinpuolen projektiin, jonka HTTP-serveri voi sitten lähettää HTML-dokumentin, JavaScript-tiedoston ja WebAssembly-binäärin käyttäjän selaimelle. WebAssembly-koodin suorittamiseksi selain tarvitsee pienen pätkän JavaScriptiä, joka tekee tarvittavat toimet WebAssembly-ohjelman käynnistämiseksi. Tämän koodin generoi puolestani cargo-web. Lisäksi JavaScriptin suorittamiseen tarvitaan yksi HTML-tiedosto. Tähän tiedostoon voi myös sisällyttää metadataa, kuten esimerkiksi sivuston otsikon, joka näkyy selaimen välilehdessä. Tähän tiedostoon linkitetään myös kaikki muu staattinen data, kuten tyylimääritykset. Nämä tiedostot laitoin käytännön mukaisesti static-nimiseen hakemistoon asiakaspuolen projektin juureen. Tämän hakemiston linkitin symbolisella linkillä palvelinpuolen projektiin, jonka HTTP-serveri voi sitten lähettää HTML-dokumentin, JavaScript-tiedoston ja WebAssembly-binäärin käyttäjän selaimelle.
\subsection{Kehys} \subsection{Kehys}
@ -108,8 +100,6 @@ Asiakaspuolen sovelluskehykseksi valitsin Yew:n\cite{yew:home}. Yew muistuttaa h
\label{sect:ulkonäkö} \label{sect:ulkonäkö}
Olen JavaScript-maailmassa tottunut siihen, että käyttöliittymäkehyksiin löytyy usein kirjasto, joka tarjoaa valmiit tyylimääritykset, mutta en löytänyt vastaavaista kirjastoa, joka toimisi Yew:n kanssa. Kaikki käyttöliittymän elementit olivat siis selaimen oletustyylisiä. En halunnut ryhtyä tässä projektissa kirjoittamaan CSS-määrityksiä alusta alkaen, joten päädyin käyttämään UIkittiä\cite{uikit}. UIkit on CSS-kirjasto, missä on paljon valmiita ja hyvännäköisiä tyylimäärityksiä. UIkitin dokumentaatio on laaja ja siellä on paljon esimerkkejä, joten alkuun pääsi todella nopeasti [kuva \ref{fig:login}]. Olen JavaScript-maailmassa tottunut siihen, että käyttöliittymäkehyksiin löytyy usein kirjasto, joka tarjoaa valmiit tyylimääritykset, mutta en löytänyt vastaavaista kirjastoa, joka toimisi Yew:n kanssa. Kaikki käyttöliittymän elementit olivat siis selaimen oletustyylisiä. En halunnut ryhtyä tässä projektissa kirjoittamaan CSS-määrityksiä alusta alkaen, joten päädyin käyttämään UIkittiä\cite{uikit}. UIkit on CSS-kirjasto, missä on paljon valmiita ja hyvännäköisiä tyylimäärityksiä. UIkitin dokumentaatio on laaja ja siellä on paljon esimerkkejä, joten alkuun pääsi todella nopeasti [kuva \ref{fig:login}].
\clearpage
\begin{figure}[h] \begin{figure}[h]
\centering \centering
\includegraphics[width=\linewidth]{illustration/login.png} \includegraphics[width=\linewidth]{illustration/login.png}
@ -156,8 +146,6 @@ Tuloksena syntyi yksinkertainen web-ohjelma, jossa on toimiva sisäänkirjautumi
\end{figure} \end{figure}
\clearpage
Ohjelman juuressa renderöidään komponentti ''ProtectedComponent'', missä on yksi nappi, jolla voidaan noutaa dataa palvelimelta. Tämä data on suojattu niin, että pyynnön mukana pitää olla eväste, jonka sisällä on JWT, joka sitten validoidaan palvelinpuolella. Jos validointi onnistuu, suojattu data lähetetään asiakkaalle. Asiakaspäässä HTTP-statuskoodin perusteella näytetään joko noudettu data, tai "403 Unauthorized". Ohjelman juuressa renderöidään komponentti ''ProtectedComponent'', missä on yksi nappi, jolla voidaan noutaa dataa palvelimelta. Tämä data on suojattu niin, että pyynnön mukana pitää olla eväste, jonka sisällä on JWT, joka sitten validoidaan palvelinpuolella. Jos validointi onnistuu, suojattu data lähetetään asiakkaalle. Asiakaspäässä HTTP-statuskoodin perusteella näytetään joko noudettu data, tai "403 Unauthorized".
Reitissä ''/login'' renderöidään ''LoginComponent'', joka koostuu kahdesta tekstikentästä, käyttäjänimi ja salasana, sekä napista, jolla kirjautumistiedot voi lähettää palvelimelle. Onnistumisen kirjautumisen jälkeen palvelimelta lähetetty eväste tallennetaan selaimen muistiin. Reitissä ''/login'' renderöidään ''LoginComponent'', joka koostuu kahdesta tekstikentästä, käyttäjänimi ja salasana, sekä napista, jolla kirjautumistiedot voi lähettää palvelimelle. Onnistumisen kirjautumisen jälkeen palvelimelta lähetetty eväste tallennetaan selaimen muistiin.