Spring Cloud - Legge til kantet 4

1. Oversikt

I vår siste Spring Cloud-artikkel la vi til Zipkin-støtte i applikasjonen vår. I denne artikkelen skal vi legge til et front-end-program i stakken vår.

Inntil nå har vi jobbet helt med bakenden for å bygge skyapplikasjonen vår. Men hva nytter det med en webapp hvis det ikke er noe brukergrensesnitt? I denne artikkelen skal vi løse problemet ved å integrere en enkeltsidesøknad i prosjektet vårt.

Vi skriver denne appen ved hjelp av Vinklet og Støvelhempe. Stilen til Angular 4-koden føles mye som å kode en Spring-app som er en naturlig crossover for en Spring-utvikler! Mens frontend-koden skal bruke Angular, kan innholdet i denne artikkelen enkelt utvides til ethvert frontend-rammeverk med minimal innsats.

I denne artikkelen skal vi bygge en Angular 4-app og koble den til våre skytjenester. Vi vil demonstrere hvordan du kan integrere pålogging mellom et SPA og Spring Security. Vi viser også hvordan du får tilgang til programmets data ved hjelp av Angular's støtte for HTTP-kommunikasjon.

2. Gateway-endringer

Med frontend på plass, skal vi bytte til skjemabasert pålogging og sikre deler av brukergrensesnittet til privilegerte brukere. Dette krever å gjøre endringer i vår gateway-sikkerhetskonfigurasjon.

2.1. Oppdater HttpSikkerhet

Først, la oss oppdatere konfigurer (HttpSecurity http) metode i vår gateway SecurityConfig.java klasse:

@ Override beskyttet ugyldig konfigurering (HttpSecurity http) {http .formLogin () .defaultSuccessUrl ("/ home / index.html", true) .and () .authorizeRequests () .antMatchers ("/ book-service / **", "/ rating-service / **", "/ login *", "/") .permitAll () .antMatchers ("/ eureka / **"). hasRole ("ADMIN") .anyRequest (). autentisert () .og () .logout () .og () .csrf (). deaktivere (); }

Først legger vi til en standard suksess-URL å peke på /home/index.html da dette vil være der Angular-appen vår bor. Deretter konfigurerer vi maurmatcherene for å tillate enhver forespørsel gjennom gatewayen bortsett fra Eureka ressurser. Dette vil delegere alle sikkerhetskontroller til back-end-tjenester.

Deretter fjernet vi URL-en for vellykket avlogging, da standard omdirigering tilbake til påloggingssiden vil fungere bra.

2.2. Legg til et hovedendepunkt

La oss deretter legge til et sluttpunkt for å returnere den autentiserte brukeren. Dette vil bli brukt i Angular-appen vår for å logge på og identifisere rollene brukeren har. Dette vil hjelpe oss med å kontrollere hvilke handlinger de kan gjøre på nettstedet vårt.

I gateway-prosjektet legger du til en AuthenticationController klasse:

@RestController offentlig klasse AuthenticationController {@GetMapping ("/ meg") offentlig rektor getMyUser (rektor) {retur rektor; }}

Kontrolleren returnerer det nåværende innloggede brukerobjektet til den som ringer. Dette gir oss all informasjonen vi trenger for å kontrollere Angular-appen vår.

2.3. Legg til en destinasjonsside

La oss legge til en veldig enkel destinasjonsside slik at brukerne ser noe når de går til roten til applikasjonen vår.

I src / main / resources / static, la oss legge til en index.html fil med lenke til påloggingssiden:

    Book Rater Landing 

Så mange flotte ting med bøkene

Logg Inn

3. Vinkel CLI og startprosjektet

Før du starter et nytt Angular-prosjekt, må du sørge for å installere de nyeste versjonene av Node.js og npm.

3.1. Installer Angular CLI

For å begynne, må vi bruke npm for å laste ned og installere Angular kommandolinjegrensesnitt. Åpne en terminal og kjør:

npm install -g @ vinkel / cli

Dette vil laste ned og installere CLI globalt.

3.2. Installer et nytt prosjekt

Mens du fortsatt er i terminalen, naviger til gateway-prosjektet og gå inn i gateway / src / hovedmappen. Lag en katalog kalt “kantet” og naviger til den. Herfra løp:

ng ny ui

Vær tålmodig; CLI setter opp et helt nytt prosjekt og laster ned alle JavaScript-avhengigheter med npm. Det er ikke uvanlig at denne prosessen tar mange minutter.

De ng kommandoen er snarveien for Angular CLI, ny parameter instruerer at CLI skal lage et nytt prosjekt, og ui kommandoen gir prosjektet vårt et navn.

3.3. Kjør prosjektet

Først når ny kommandoen er fullført. Naviger til ui mappe som ble opprettet og kjørt:

ng server

Når prosjektet er bygd, naviger til // localhost: 4200. Vi bør se dette i nettleseren:

Gratulerer! Vi har nettopp bygget en Angular-app!

3.4. Installer Bootstrap

La oss bruke npm for å installere bootstrap. Kjør denne kommandoen fra ui-katalogen:

npm install [e-postbeskyttet] - lagre

Dette laster ned bootstrap til mappen node_modules.

I ui katalog, åpne .angular-cli.json fil. Dette er filen som konfigurerer noen egenskaper for prosjektet vårt. Finn apper> stiler eiendom og legg til en filplassering av Bootstrap CSS-klassen:

"styles": ["styles.css", "../node_modules/bootstrap/dist/css/bootstrap.min.css"],

Dette vil instruere Angular om å inkludere Bootstrap i den kompilerte CSS-filen som er bygget sammen med prosjektet.

3.5. Angi katalogen for utdata for bygg

Deretter må vi fortelle Angular hvor vi skal plassere build-filene slik at våroppstartsappen kan tjene dem. Spring Boot kan servere filer fra to steder i ressursmappen:

  • src / hoved / ressurser / statisk
  • src / main / resource / public

Siden vi allerede bruker den statiske mappen for å betjene noen ressurser for Eureka, og Angular sletter denne mappen hver gang en build kjøres, la oss bygge vår Angular-app til den offentlige mappen.

Åpne .angular-cli.json fil igjen og finn apper> outDir eiendom. Oppdater det streng:

"outDir": "../../resources/static/home",

Hvis Angular-prosjektet er lokalisert i src / main / angular / ui, vil det bygge til mappen src / main / resources / public. Hvis appen i en annen mappe, må denne strengen endres for å angi plasseringen riktig.

3.6. Automatiser Build With Maven

Til slutt vil vi sette opp en automatisert build som skal kjøres når vi kompilerer koden vår. Denne mauroppgaven vil kjøre Angular CLI build-oppgaven når “mvn compile” kjøres. Legg til dette trinnet i gatewayens POM.xml for å sikre at hver gang vi kompilerer får vi de siste ui-endringene:

 maven-antrun-plugin genererer ressurser 

Vi må merke oss at dette oppsettet krever at Angular CLI er tilgjengelig på klassestien. Å skyve dette skriptet til et miljø som ikke har den avhengigheten, vil føre til byggfeil.

La oss nå begynne å bygge vår Angular-applikasjon!

4. Vinklet

I denne delen av opplæringen bygger vi en autentiseringsmekanisme på siden vår. Vi bruker grunnleggende autentisering og følger en enkel flyt for å få det til å fungere.

Brukere har et påloggingsskjema der de kan skrive inn brukernavn og passord.

Deretter bruker vi legitimasjonen deres til å lage et base64-godkjenningstoken og be om "/meg" endepunkt. Endepunktet returnerer a Rektor objekt som inneholder rollene til denne brukeren.

Til slutt lagrer vi legitimasjonen og rektoren på klienten som skal brukes i etterfølgende forespørsler.

La oss se hvordan dette er gjort!

4.1. Mal

Gå til gateway-prosjektet src / main / vinkel / ui / src / app og åpne app.component.html fil. Dette er den første malen som Angular laster og vil være der brukerne våre vil lande etter innlogging.

Her skal vi legge til litt kode for å vise en navigasjonsfelt med et påloggingsskjema:

    Book Rater Admin 
    Logg ut

    Alle kan se bøkene.

    Brukere kan se og opprette rangeringer

    Administratorer kan gjøre hva som helst!

    Denne koden setter opp en navigasjonsfelt med Bootstrap-klasser. Innebygd i linjen er et innebygd påloggingsskjema. Angular bruker denne markeringen til å samhandle med JavaScript dynamisk for å gjengi forskjellige deler av siden og kontrollere ting som skjemainnlevering.

    Uttalelser som (ngSubmit) = ”onLogin (f)” bare angi at når skjemaet sendes, ring metoden “OnLogin (f)” og send skjemaet til den funksjonen. Innen jumbotron div, vi har avsnittstagger som vil vises dynamisk avhengig av tilstanden til vårt hovedobjekt.

    Deretter la oss kode opp Typescript-filen som støtter denne malen.

    4.2. Typeskrift

    Åpne filen app.component.ts fra samme katalog. I denne filen vil vi legge til alle typeskriftegenskapene og metodene som kreves for å gjøre malfunksjonen vår:

    importer {Component} fra "@ vinkel / kjerne"; importer {Principal} fra "./principal"; importer {Response} fra "@ angular / http"; importer {Book} fra "./book"; importer {HttpService} fra "./http.service"; @Component ({selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css']}) eksportklasse AppComponent {valgt bok: bok = null; rektor: rektor = ny rektor (usann, []); loginFailed: boolsk = usann; konstruktør (privat httpService: HttpService) {} ngOnInit (): ugyldig {this.httpService.me (). abonner ((respons: Response) => {let principalJson = response.json (); this.principal = ny rektor (principalJson .autentisert, principalJson.authorities);}, (error) => {console.log (error);}); } onLogout () {this.httpService.logout (). abonner ((respons: Response) => {if (response.status === 200) {this.loginFailed = false; this.principal = new Principal (false, [ ]); window.location.replace (response.url);}}, (error) => {console.log (error);}); }}

    Denne klassen hekter seg inn i Angular livssyklusmetoden, ngOnInit (). I denne metoden kaller vi /meg sluttpunkt for å få brukerens nåværende rolle og tilstand. Dette bestemmer hva brukeren ser på hovedsiden. Denne metoden vil bli utløst når denne komponenten opprettes, og det er en flott tid å sjekke brukerens egenskaper for tillatelser i appen vår.

    Vi har også en onLogout () metode som logger ut brukeren vår og gjenoppretter tilstanden til denne siden til de opprinnelige innstillingene.

    Det skjer litt magi her skjønt. De httpService eiendom som er erklært i konstruktøren. Angular injiserer denne egenskapen i klassen vår under kjøretid. Angular administrerer enkelte forekomster av serviceklasser og injiserer dem ved hjelp av konstruktørinjeksjon, akkurat som våren!

    Deretter må vi definere HttpService klasse.

    4.3. HttpService

    Opprett en fil med samme navn i samme katalog “Http.service.ts”. I denne filen legger du til denne koden for å støtte påloggings- og avloggingsmetodene:

    importer {Injectable} fra "@ vinkel / kjerne"; importer {Observable} fra "rxjs"; importer {Response, Http, Headers, RequestOptions} fra "@ angular / http"; importer {Book} fra "./book"; importer {Rating} fra "./rating"; @Injectable () eksportklasse HttpService {constructor (privat http: Http) {} meg (): Observerbar {returner this.http.get ("/ meg", this.makeOptions ())} logout (): Observable {return this .http.post ("/ logout", '', this.makeOptions ())} private makeOptions (): RequestOptions {let headers = new Headers ({'Content-Type': 'application / json'}); returner nye RequestOptions ({headers: headers}); }}

    I denne klassen injiserer vi en annen avhengighet ved å bruke Angular's DI-konstruksjon. Denne gangen er det Http klasse. Denne klassen håndterer all HTTP-kommunikasjon og blir gitt oss av rammeverket.

    Disse metodene utfører hver en HTTP-forespørsel ved bruk av angular's HTTP-bibliotek. Hver forespørsel spesifiserer også en innholdstype i overskriftene.

    Nå må vi gjøre en ting til for å få HttpService registrert i avhengighetsinjeksjonssystemet. Åpne app.module.ts fil og finn leverandørens eiendom. Legg til HttpService til den matrisen. Resultatet skal se slik ut:

    leverandører: [HttpService],

    4.4. Legg til rektor

    La oss deretter legge til vårt viktigste DTO-objekt i typeskriptkoden. I samme katalog legger du til en fil som heter “principal.ts” og legger til denne koden:

    eksportklasse Rektor {offentlig godkjent: boolsk; offentlige myndigheter: Myndighet [] = []; offentlig legitimasjon: noen; konstruktør (godkjent: boolsk, autoritet: hvilken som helst [], legitimasjon: hvilken som helst) {this.authenticated = authenticated; autoriteter.map (auth => this.authorities.push (new Authority (auth.authority))) this.credentials = credentials; } isAdmin () {returner this.authorities.some ((auth: Authority) => auth.authority.indexOf ('ADMIN')> -1)}} eksportklasse Authority {public Authority: String; konstruktør (autoritet: String) {this.authority = autoritet; }}

    Vi la til Rektor klasse og en Autoritet klasse. Dette er to DTO-klasser, omtrent som POJOer i en vår-app. På grunn av det trenger vi ikke å registrere disse klassene med DI-systemet i vinkel.

    Deretter la oss konfigurere en viderekoblingsregel for å omdirigere ukjente forespørsler til roten til applikasjonen vår.

    4.5. 404 Håndtering

    La oss gå tilbake til Java-koden for gateway-tjenesten. I hvor GatewayApplication klasse bor, legg til en ny klasse som heter ErrorPageConfig:

    @Component public class ErrorPageConfig implementerer ErrorPageRegistrar {@Override public void registerErrorPages (ErrorPageRegistry registry) {registry.addErrorPages (new ErrorPage (HttpStatus.NOT_FOUND, "/home/index.html")); }}

    Denne klassen vil identifisere ethvert 404-svar og omdirigere brukeren til “/Home/index.html”. I en enkeltsidesapp håndterer vi all trafikk som ikke går til en dedikert ressurs, siden klienten skal håndtere alle navigerbare ruter.

    Nå er vi klare til å fyre opp denne appen og se hva vi bygde!

    4.6. Bygg og vis

    Kjør nå “mvn kompilere”Fra gateway-mappen. Dette vil samle Java-kilden vår og bygge Angular-appen til den offentlige mappen. La oss starte de andre skyapplikasjonene: config, oppdagelse, og zipkin. Kjør deretter gateway-prosjektet. Når tjenesten starter, naviger til // lokal vert: 8080 for å se appen vår. Vi burde se noe slikt:

    La oss deretter følge lenken til påloggingssiden:

    Logg inn med bruker- / passordlegitimasjonen. Klikk på "Logg inn", så skal vi omdirigeres til /home/index.html der appen vår for enkeltsider lastes inn.

    Det ser ut som vårt jumbotron indikerer at vi er logget inn som bruker! Logg deg ut ved å klikke på lenken øverst til høyre og logge på med admin / admin legitimasjon denne gangen.

    Ser bra ut! Nå er vi logget på som administrator.

    5. Konklusjon

    I denne artikkelen har vi sett hvor enkelt det er å integrere en enkeltsidesapp i skysystemet vårt. Vi tok et moderne rammeverk og integrerte en fungerende sikkerhetskonfigurasjon i applikasjonen vår.

    Bruk disse eksemplene, og prøv å skrive noen kode for å ringe til boktjeneste eller vurderingstjeneste. Siden vi nå har eksempler på å ringe HTTP-samtaler og kablingsdata til malene, bør dette være relativt enkelt.

    Hvis du vil se hvordan resten av nettstedet er bygget som alltid, kan du finne kildekoden på Github.


    $config[zx-auto] not found$config[zx-overlay] not found