How to create ionic angular project?

Håndtering af Brugerlogins og Sessioner i Ionic Apps

29/11/2021

Rating: 4.76 (9432 votes)

I den dynamiske verden af mobilapp-udvikling er en af de mest afgørende funktioner evnen til at administrere brugerlogins og opretholde brugersessioner. Dette sikrer ikke kun en personlig oplevelse for hver bruger, men forbedrer også sikkerheden og brugervenligheden markant. Ionic, som et førende open-source framework til udvikling af tværplatformsmobilapps, tilbyder robuste værktøjer og metoder til at opnå netop dette. Baseret på webkomponenter og populære frontend-frameworks som Angular, giver Ionic udviklere mulighed for at bygge native-lignende applikationer med webteknologier. Men spørgsmålet forbliver: Kan Ionic huske loggede brugere, og hvordan implementerer man en sikker og effektiv login-flow? Denne artikel vil dykke ned i disse spørgsmål og give en omfattende vejledning i, hvordan du håndterer brugerautentificering, sessioner og app-sikkerhed i dine Ionic-projekter.

Can ionic Serve Remember logged users?
Indholdsfortegnelse

Hvad er Ionic, og hvordan starter man et projekt?

Ionic er et kraftfuldt SDK (Software Development Kit) med et open-source UI-bibliotek, der gør det muligt for webudviklere at bygge højtydende, tværplatformsmobil- og desktop-apps ved hjælp af webteknologier som HTML, CSS og JavaScript. Dens styrke ligger i at udnytte eksisterende webfærdigheder til at skabe apps, der kan køre på iOS, Android og som Progressive Web Apps (PWA'er) fra en enkelt kodebase.

At starte et nyt Ionic-projekt er en ligetil proces. Først skal du sikre dig, at du har Node.js og Ionic CLI (Command Line Interface) installeret på din maskine. Når det er på plads, kan du oprette et nyt projekt med en simpel kommando:

ionic start mitNyProjekt tabs --type=angular --capacitor

Denne kommando vil:

  • Oprette en ny mappe kaldet mitNyProjekt.
  • Bruge tabs-skabelonen, som er en populær startskabelon med navigationsfaner. Ionic tilbyder også andre skabeloner som sidemenu (med en sidebaseret menu), blank (en tom side) og super (en mere omfattende startskabelon).
  • Angive --type=angular for at specificere Angular som frontend-framework (Ionic understøtter også React og Vue).
  • Inkludere --capacitor, som er Ionic's foretrukne native runtime til at bygge og køre web-apps på native enheder.

Efter at projektet er oprettet, navigerer du ind i projektmappen (cd mitNyProjekt) og kan køre appen i din browser med ionic serve. Dette giver dig en lokal udviklingsserver, hvor du kan se dine ændringer i realtid. Projektstrukturen vil typisk indeholde src/app, hvor dine komponenter, sider og tjenester er placeret, samt konfigurationsfiler.

Administrering af brugerlogins og sessioner i Ionic

Spørgsmålet om, hvorvidt Ionic kan huske loggede brugere, er afgørende for en god brugeroplevelse. Svaret er et rungende ja, men det kræver en bevidst implementering. Ionic i sig selv lagrer ikke brugersessioner, da det er et frontend-framework. Opgaven med at huske en bruger falder typisk på en kombination af klient-side lagring og backend-autentificering.

Klient-side Lagring af Brugerdata

For at huske en bruger skal appen lagre en form for identifikator på enheden, såsom et autentificeringstoken eller en sessions-ID. Når appen startes, kan den tjekke for tilstedeværelsen af dette token. Hvis et token findes, kan det bruges til at validere brugerens session med backend'en.

What should I learn in ionic?
At the end you’ll have a complete understanding about routing, securing your app, using guards and reactive forms and all the basics to start your next Ionic app! If you need help with boilerplate more often, also check out my tool KickoffIonic.

De mest almindelige metoder til klient-side lagring i Ionic inkluderer:

  • Capacitor Storage: Dette plugin er den anbefalede måde at gemme data persistent på tværs af app-genstarter. Det er et simpelt nøgle-værdi-lager, der fungerer på tværs af alle platforme (web, iOS, Android). Det er ideelt til at gemme JWT (JSON Web Tokens) eller andre sessionsspecifikke data.
  • LocalStorage: En browser-API, der er tilgængelig i PWA'er og i Ionic-apps, når de kører i en browser. Selvom det er nemt at bruge, er det mindre sikkert for følsomme data og bør ikke være den eneste lagringsmetode for native apps.

Når et token er gemt, kan appen ved opstart hente dette token og bruge det til at "genoprette" brugerens session, ofte ved at foretage et API-kald til backend'en for at validere tokenet og hente brugerprofilen.

Backend-autentificering

Den virkelige "hukommelse" af en bruger sker på backend-serveren. Når en bruger logger ind, sender backend'en et token tilbage til klienten, som derefter gemmes lokalt. Ved efterfølgende forespørgsler sender appen dette token med, og backend'en validerer det for at sikre, at brugeren er autentificeret og autoriseret.

Tjenester som Back4App Parse (som vi vil udforske senere) eller Firebase Authentication tilbyder færdige løsninger til brugerstyring, der inkluderer funktionalitet til at huske brugere på tværs af sessioner. De bruger ofte en kombination af tokens og session-cookies til at opretholde tilstanden.

Implementering af Autentificering og Sikkerhed

En robust autentificeringsproces er afgørende. I Ionic-apps, især dem bygget med Angular, opnås dette typisk gennem en kombination af tjenester (services), reaktive formularer (reactive forms) og rutebeskyttere (guards).

How do I create a project using ionic?
Once you have installed ionic on your system, start a new project by running this in your terminal. Next fire up your IDE, Visual Studio Code in my case and open your newly created projected. In your project, you’ll have a homepage already setup for you by ionic, but let’s create a separate login page to start our design.

Autentificeringstjenesten (Authentication Service)

Det er god praksis at indkapsle al autentificeringslogik i en dedikeret service. Denne service håndterer login, logout, registrering og vedligeholdelse af brugerens autentificeringsstatus.

import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { map, tap, switchMap, filter, take } from 'rxjs/operators'; import { BehaviorSubject, from, Observable } from 'rxjs'; import { Storage } from '@capacitor/storage'; const TOKEN_KEY = 'my-token'; @Injectable({ providedIn: 'root' }) export class AuthenticationService { isAuthenticated: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(null); token = ''; constructor(private http: HttpClient) { this.loadToken(); } async loadToken() { const token = await Storage.get({ key: TOKEN_KEY }); if (token && token.value) { this.token = token.value; this.isAuthenticated.next(true); } else { this.isAuthenticated.next(false); } } login(credentials: { email; password }): Observable<any> { return this.http.post(`https://reqres.in/api/login`, credentials).pipe( map((data: any) => data.token), switchMap((token) => { return from(Storage.set({ key: TOKEN_KEY, value: token })); }), tap((_) => { this.isAuthenticated.next(true); }) ); } logout(): Promise<void> { this.isAuthenticated.next(false); return Storage.remove({ key: TOKEN_KEY }); } } 

I denne service:

  • isAuthenticated er en BehaviorSubject, der udsender den aktuelle autentificeringsstatus. Denne bruges af guards og andre komponenter til at reagere på login/logout.
  • loadToken() forsøger at hente et gemt token fra Capacitor Storage ved app-start. Hvis et token findes, sættes isAuthenticated til true.
  • login() sender login-oplysninger til en backend, modtager et token, gemmer det og opdaterer isAuthenticated.
  • logout() fjerner tokenet fra lagring og opdaterer status.

Rutebeskyttere (Guards) for Sikkerhed

Angular-routeren tilbyder Guards, som er specifikke klasser, der kan forhindre eller tillade navigation til bestemte ruter. De er essentielle for app-sikkerhed og for at kontrollere flowet, f.eks. introduktionssider eller automatisk login.

De mest relevante guards er:

  • CanLoad: Forhindrer lazy-loaded moduler i at blive indlæst, hvis brugeren ikke har adgang. Dette er den mest sikre metode, da koden slet ikke indlæses.
  • CanActivate: Tillader eller forhindrer aktivering af en rute.

Eksempler på guards:

IntroGuard: Til introduktionssiden

Denne guard tjekker, om brugeren allerede har set introduktionssiden. Hvis ikke, omdirigeres de dertil.

import { Injectable } from '@angular/core'; import { CanLoad, Router } from '@angular/router'; import { Storage } from '@capacitor/storage'; export const INTRO_KEY = 'intro-seen'; @Injectable({ providedIn: 'root' }) export class IntroGuard implements CanLoad { constructor(private router: Router) { } async canLoad(): Promise<boolean> { const hasSeenIntro = await Storage.get({ key: INTRO_KEY }); if (hasSeenIntro && (hasSeenIntro.value === 'true')) { return true; // Har set intro, tillad navigation } else { this.router.navigateByUrl('/intro', { replaceUrl: true }); return false; // Har ikke set intro, omdiriger til intro-side } } } 

AutoLoginGuard: Automatisk login

Denne guard tjekker ved app-start, om der allerede er en gyldig session. Hvis ja, omdirigeres brugeren direkte til den indloggede del af appen.

import { Injectable } from '@angular/core'; import { CanLoad, Router } from '@angular/router'; import { Observable } from 'rxjs'; import { AuthenticationService } from '../services/authentication.service'; import { filter, map, take } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class AutoLoginGuard implements CanLoad { constructor(private authService: AuthenticationService, private router: Router) { } canLoad(): Observable<boolean> { return this.authService.isAuthenticated.pipe( filter((val) => val !== null), // Filtrer initial 'null' værdi take(1), // Tag kun én værdi og fuldfør map((isAuthenticated) => { if (isAuthenticated) { this.router.navigateByUrl('/tabs', { replaceUrl: true }); return false; // Omdirigeret, så bloker adgang til login-siden } else { return true; // Ikke logget ind, tillad adgang til login-siden } }) ); } } 

AuthGuard: Beskyttelse af indloggede områder

Denne guard sikrer, at kun autentificerede brugere kan få adgang til bestemte ruter. Hvis ikke autentificeret, omdirigeres de til login-siden.

How to use ionic in back4app parse?
You can do it by running: Open your app.component.ts, import parse and initialize its connection to Back4App Parse server. If you don’t know how to find your keys, check out the first Ionic tutorial Start From Template. Now, let’s create our LogIn page. Luckly, Ionic does everything to us. All we need to do is to run the following command:
import { AuthenticationService } from './../services/authentication.service'; import { Injectable } from '@angular/core'; import { CanLoad, Router } from '@angular/router'; import { Observable } from 'rxjs'; import { filter, map, take } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanLoad { constructor(private authService: AuthenticationService, private router: Router) { } canLoad(): Observable<boolean> { return this.authService.isAuthenticated.pipe( filter((val) => val !== null), take(1), map((isAuthenticated) => { if (isAuthenticated) { return true; // Autentificeret, tillad adgang } else { this.router.navigateByUrl('/login'); return false; // Ikke autentificeret, omdiriger til login } }) ); } } 

Ved at anvende disse guards i din routing-modul (f.eks. app-routing.module.ts), kan du definere komplekse navigationsflows og sikre din app effektivt. For eksempel kan /tabs-ruten beskyttes med AuthGuard, mens /login-ruten kan bruge IntroGuard og AutoLoginGuard.

Bygning af Responsive Login- og Registreringsformularer

Brugergrænsefladen for login og registrering skal være intuitiv og responsiv for at fungere godt på tværs af forskellige enhedsstørrelser. Ionic's komponenter er designet til at være responsive ud af boksen.

Reaktive Formularer (Reactive Forms)

Angulars reaktive formularer tilbyder en robust og skalerbar måde at håndtere formularinput og validering på. Du definerer formularstrukturen og valideringsreglerne i TypeScript-koden, hvilket gør det nemt at teste og administrere.

Eksempel på login-side (login.page.ts):

import { AuthenticationService } from './../../services/authentication.service'; import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { AlertController, LoadingController } from '@ionic/angular'; import { Router } from '@angular/router'; @Component({ selector: 'app-login', templateUrl: './login.page.html', styleUrls: ['./login.page.scss'] }) export class LoginPage implements OnInit { credentials: FormGroup; constructor( private fb: FormBuilder, private authService: AuthenticationService, private alertController: AlertController, private router: Router, private loadingController: LoadingController ) { } ngOnInit() { this.credentials = this.fb.group({ email: ['[email protected]', [Validators.required, Validators.email]], password: ['cityslicka', [Validators.required, Validators.minLength(6)]] }); } async login() { const loading = await this.loadingController.create(); await loading.present(); this.authService.login(this.credentials.value).subscribe( async (res) => { await loading.dismiss(); this.router.navigateByUrl('/tabs', { replaceUrl: true }); }, async (res) => { await loading.dismiss(); const alert = await this.alertController.create({ header: 'Login mislykkedes', message: res.error.error, buttons: ['OK'] }); await alert.present(); } ); } get email() { return this.credentials.get('email'); } get password() { return this.credentials.get('password'); } } 

Tilsvarende kan HTML-skabelonen (login.page.html) struktureres med Ionic-komponenter og Angulars direktiver til validering og fejlvisning:

<ion-header> <ion-toolbar color="primary"> <ion-title>Devdactic App</ion-title> </ion-toolbar> </ion-header> <ion-content> <form (ngSubmit)="login()" [formGroup]="credentials"> <div class="input-group"> <ion-item> <ion-input type="email" placeholder="Email" formControlName="email"></ion-input> </ion-item> <div *ngIf="(email.dirty || email.touched) && email.errors" class="errors"> <span *ngIf="email.errors?.required">Email er påkrævet</span> <span *ngIf="email.errors?.email">Email er ugyldig</span> </div> <ion-item> <ion-input type="password" placeholder="Adgangskode" formControlName="password"></ion-input> </ion-item> <div *ngIf="(password.dirty || password.touched) && password.errors" class="errors"> <span *ngIf="password.errors?.required">Adgangskode er påkrævet</span> <span *ngIf="password.errors?.minlength">Adgangskode skal være mindst 6 tegn</span> </div> </div> <ion-button type="submit" expand="block" [disabled]="!credentials.valid">Log ind</ion-button> <ion-button type="button" expand="block" color="light" fill="clear">Ikke medlem endnu? Tilmeld dig!</ion-button> </form> </ion-content> 

CSS (login.page.scss) kan bruges til at tilføje visuel appel og sikre responsivitet:

ion-content { --padding-top: 40%; --padding-start: 10%; --padding-end: 10%; --background: url('https://images.unsplash.com/photo-1536431311719-398b6704d4cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1234&q=80') 0 0/100% 100% no-repeat; } .input-group { background: #fff; border-radius: 10px; overflow: hidden; margin-bottom: 15px; } .errors { font-size: small; color: #fff; background: var(--ion-color-danger); padding-left: 15px; padding-top: 5px; padding-bottom: 5px; } 

Dette design giver en centreret formular med en flot baggrund på mobile enheder og kan nemt tilpasses med mediespørgsmål for at vise en omkranset boks på tablets/desktops, som nævnt i eksemplerne.

Can ionic Serve Remember logged users?

Integration med Backend-tjenester (f.eks. Back4App Parse)

Mens Ionic håndterer frontend-delen, er en backend-tjeneste afgørende for at administrere brugere, databaser og forretningslogik. Back4App Parse er et populært valg, der tilbyder en komplet backend-løsning med funktionalitet til brugerstyring, databaselagring og mere.

Her er hvordan du kan integrere Ionic med Back4App Parse for at håndtere login og registrering:

Installation og Opsætning

Først skal du installere Parse SDK i dit Ionic-projekt:

npm install parse

Derefter initialiserer du Parse i din app's hovedkomponent (f.eks. app.component.ts) med dine Back4App-nøgler:

import * as Parse from 'parse'; // ... andre imports @Component({ /* ... */ }) export class AppComponent { constructor() { Parse.initialize("DIN_APP_ID", "DIN_JS_NØGLE"); Parse.serverURL = 'https://parseapi.back4app.com/'; this.checkCurrentUser(); // Tjek for logget bruger ved opstart } async checkCurrentUser() { try { const user = await Parse.User.currentAsync(); if (user) { // Bruger er logget ind, omdiriger til hjemmeside // this.navCtrl.setRoot('homepage'); // Eksempel med Ionic 3 stil // For Angular Router: this.router.navigateByUrl('/tabs'); } else { // Ingen bruger, omdiriger til login // this.navCtrl.setRoot('loginpage'); // For Angular Router: this.router.navigateByUrl('/login'); } } catch (error) { console.error('Fejl ved hentning af logget bruger:', error); // Omdiriger til login i tilfælde af fejl // this.router.navigateByUrl('/login'); } } } 

Parse.User.currentAsync() er en nøglefunktion her. Den returnerer den aktuelt loggede bruger (hvis nogen) eller null, hvilket gør det muligt for din app at huske sessioner på tværs af genstarter. Dette er den primære mekanisme, der giver Ionic-apps mulighed for at "huske" brugere uden at kræve genindtastning af legitimationsoplysninger ved hver app-start (medmindre brugeren logger ud).

Login, Registrering og Logout med Parse

Du kan bruge Parse SDK's metoder direkte i din autentificeringstjeneste eller dine login/registreringssider:

Registrering:

async signup() { const user = new Parse.User(); user.set("username", this.username); user.set("password", this.password); try { await user.signUp(); console.log('Bruger oprettet succesfuldt'); // Vis succesmeddelelse og omdiriger } catch (error) { console.error('Fejl ved registrering:', error); // Vis fejlmeddelelse } } 

Login:

async signin() { try { const user = await Parse.User.logIn(this.username, this.password); console.log('Logget ind succesfuldt', user); // Omdiriger til hjemmeside } catch (error) { console.error('Fejl ved login:', error); // Vis fejlmeddelelse } } 

Logout:

async logout() { try { await Parse.User.logOut(); console.log('Logget ud succesfuldt'); // Omdiriger til login-side } catch (error) { console.error('Fejl ved logout:', error); // Vis fejlmeddelelse } } 

Disse eksempler viser, hvordan en backend-tjeneste som Back4App Parse problemfrit kan integreres med din Ionic-app for at levere fuldgyldig brugerstyring.

Sammenligning af Autentificeringsmetoder

Der er flere tilgange til at håndtere autentificering i Ionic-apps. Her er en kort sammenligning:

MetodeBeskrivelseFordeleUlemper
Token-baseret (JWT)Backend udsteder et JSON Web Token (JWT) ved login, som gemmes i klienten (f.eks. Capacitor Storage) og sendes med hver forespørgsel.Stateless (skalerbar), bredt understøttet, sikker med HTTPS.Kræver manuel tokenfornyelse, kan være komplekst at implementere sikkert.
Session-baseret (Cookies)Backend opretter en session og sender en session-cookie til klienten. Sesions-ID gemmes i cookien.Enkel at implementere med traditionelle servere, automatisk sessionsstyring.Mindre skalerbar (stateful), sårbar over for CSRF-angreb uden korrekt konfiguration, cookies kan have SameSite-begrænsninger.
OAuth/OpenID ConnectBruger en tredjepartsudbyder (Google, Facebook) til autentificering. Klienten modtager et token fra udbyderen.Nem social login, uddelegerer sikkerhedsansvar, forbedret brugeroplevelse.Afhængighed af tredjeparter, kan være mere komplekst at sætte op.
Backend-as-a-Service (BaaS)Færdige løsninger som Firebase, Back4App Parse, AWS Amplify, der håndterer autentificering og databaser.Hurtig udvikling, mindre backend-kode, skalerbarhed indbygget.Vendor lock-in, mindre fleksibilitet til tilpasset logik, potentielt højere omkostninger ved stor skala.

Ofte Stillede Spørgsmål (FAQ)

Hvad er fordelene ved at bruge Ionic til mobilapps?
Ionic giver dig mulighed for at bygge én kodebase, der kan implementeres på flere platforme (iOS, Android, Web), hvilket sparer tid og ressourcer. Det udnytter webudvikleres eksisterende HTML-, CSS- og JavaScript-færdigheder, har et rigt UI-komponentbibliotek og er yderst performant takket være Capacitor og webkomponenter.
Hvordan sikrer jeg min Ionic-app?
Sikkerhed i Ionic involverer flere lag: brug altid HTTPS til kommunikation med din backend, valider input på både klient- og serversiden, brug sikre lagringsmetoder (f.eks. Capacitor Storage) til følsomme data, implementer robuste autentificerings- og autorisationsmekanismer (som JWT og Guards), og hold dine afhængigheder opdaterede.
Kan jeg bruge enhver backend med Ionic?
Ja, Ionic er frontend-agnostisk og kan forbinde til enhver backend, der udstiller en API (f.eks. REST, GraphQL). Dette inkluderer populære BaaS-løsninger som Firebase og Back4App Parse, samt brugerdefinerede Node.js-, Python-, PHP- eller .NET-backends.
Hvad er Reactive Forms i Angular/Ionic?
Reactive Forms er en model-drevet tilgang til at håndtere formularinput i Angular. De giver en mere forudsigelig og skalerbar måde at administrere formularer på, især i komplekse scenarier. De tilbyder stærk typetjek, synkron og asynkron validering og nem testbarhed.
Hvad er en "Guard" i Angular-routing?
En Guard er en funktion eller klasse i Angular, der bestemmer, om routeren kan navigere til en given rute. De bruges til at implementere autorisationslogik, forhindre adgang til visse sider baseret på brugerens tilstand (f.eks. logget ind/ud), eller for at bekræfte, at brugeren har set en introduktionsside.

Konklusion

At administrere brugerlogins og sessioner er en grundlæggende, men kompleks del af enhver moderne mobilapp. Ionic, kombineret med kraften fra Angular, Capacitor Storage og en veludviklet backend-strategi, giver udviklere alle de nødvendige værktøjer til at skabe sikre, effektive og brugervenlige autentificeringsflows. Ved at udnytte reaktive formularer til inputhåndtering og Guards til rutebeskyttelse kan du sikre en robust applikation, der ikke kun husker dine brugere, men også beskytter deres data og giver en gnidningsfri oplevelse. Uanset om du vælger en BaaS-løsning som Back4App Parse eller en brugerdefineret backend, er principperne for sikkerhed og sessionsstyring universelle og afgørende for succes.

Hvis du vil læse andre artikler, der ligner Håndtering af Brugerlogins og Sessioner i Ionic Apps, kan du besøge kategorien Mobiludvikling.

Go up