Spring Security-inlogpagina met Angular

1. Overzicht

In deze zelfstudie maken we een inlogpagina met Spring Security met:

  • AngularJS
  • Hoekig 2, 4, 5 en 6

De voorbeeldtoepassing die we hier gaan bespreken, bestaat uit een clienttoepassing die communiceert met de REST-service, beveiligd met standaard HTTP-authenticatie.

2. Lente-beveiligingsconfiguratie

Laten we eerst de REST API instellen met Spring Security en Basic Auth:

Hier is hoe het is geconfigureerd:

@Configuration @EnableWebSecurity openbare klasse BasicAuthConfiguration breidt WebSecurityConfigurerAdapter uit {@Override protected void configure (AuthenticationManagerBuilder auth) genereert Uitzondering {auth .inMemoryAuthentication () .withUser ("user") .password ("password") .roles; ("password") .roles; ("password") .roles; } @Override protected void configure (HttpSecurity http) gooit uitzondering {http.csrf (). Disable () .authorizeRequests () .antMatchers ("/ login"). AllowAll () .anyRequest () .authenticated () .and () .httpBasic (); }}

Laten we nu de eindpunten maken. Onze REST-service heeft er twee: een om in te loggen en de andere om de gebruikersgegevens op te halen:

@RestController @CrossOrigin openbare klasse UserController {@RequestMapping ("/ login") openbare booleaanse login (@RequestBody User user) {return user.getUserName (). Equals ("user") && user.getPassword (). Equals ("wachtwoord "); } @RequestMapping ("/ user") openbare hoofdgebruiker (verzoek HttpServletRequest) {String authToken = request.getHeader ("Authorization") .substring ("Basic" .length ()). Trim (); return () -> nieuwe string (Base64.getDecoder () .decode (authToken)). split (":") [0]; }}

Evenzo kunt u onze andere tutorial over Spring Security OAuth2 bekijken als u geïnteresseerd bent in het implementeren van een OAuth2-server voor autorisatie.

3. Het opzetten van de Angular Client

Nu we de REST-service hebben gemaakt, gaan we de inlogpagina opzetten met verschillende versies van de Angular-client.

De voorbeelden die we hier gaan zien, gebruiken npm voor afhankelijkheidsbeheer en nodejs voor het uitvoeren van de applicatie.

Angular gebruikt een architectuur van één pagina waar alle onderliggende componenten (in ons geval zijn dit login- en homecomponenten) worden geïnjecteerd in een gemeenschappelijke bovenliggende DOM.

In tegenstelling tot AngularJS, dat JavaScript gebruikt, gebruikt Angular versie 2 en hoger TypeScript als hoofdtaal. Daarom heeft de applicatie ook bepaalde ondersteunende bestanden nodig die nodig zijn om correct te werken.

Vanwege de incrementele verbeteringen van Angular, verschillen de benodigde bestanden van versie tot versie.

Laten we vertrouwd raken met elk van deze:

  • systemjs.config.js - systeemconfiguraties (versie 2)
  • package.json - afhankelijkheden van knooppuntmodules (vanaf versie 2)
  • tsconfig.json - root-level Typescript-configuraties (vanaf versie 2)
  • tsconfig.app.json - Applicatieniveau Typoscript-configuraties (vanaf versie 4)
  • .hoekig-cli.json - Hoekige CLI-configuraties (versie 4 en 5)
  • angular.json - Hoekige CLI-configuraties (vanaf versie 6)

4. Inlogpagina

4.1. AngularJS gebruiken

Laten we het index.html bestand en voeg de relevante afhankelijkheden eraan toe:

Aangezien dit een applicatie met één pagina is, worden alle onderliggende componenten toegevoegd aan het div-element met ng-view attribuut op basis van de routeringslogica.

Laten we nu het app.js die de URL naar componenttoewijzing definieert:

(function () {'use strict'; angular .module ('app', ['ngRoute']) .config (config) .run (run); config. $ inject = ['$ routeProvider', '$ locationProvider' ]; function config ($ routeProvider, $ locationProvider) {$ routeProvider.when ('/', {controller: 'HomeController', templateUrl: 'home / home.view.html', controllerAs: 'vm'}). when ( '/ login', {controller: 'LoginController', templateUrl: 'login / login.view.html', controllerAs: 'vm'}). anders ({redirectTo: '/ login'});} run. $ inject = ['$ rootScope', '$ location', '$ http', '$ window']; functierun ($ rootScope, $ location, $ http, $ window) {var userData = $ window.sessionStorage.getItem ('userData '); if (userData) {$ http.defaults.headers.common [' Authorization '] =' Basic '+ JSON.parse (userData) .authData;} $ rootScope. $ on (' $ locationChangeStart ', function (event , next, current) {var restrictedPage = $ .inArray ($ location.path (), ['/ login']) === -1; var ingelogd = $ window.sessionStorage.getItem ('userData'); if ( limitedPage &&! ingelogd) {$ location.pat h ('/ login'); }}); }}) ();

De login-component bestaat uit twee bestanden, de login.controller.js, en de login.view.html.

Laten we naar de eerste kijken:

Log in

Gebruikersnaam Gebruikersnaam is vereist Wachtwoord Wachtwoord is vereist Inloggen

en de tweede:

(function () {'use strict'; angular .module ('app') .controller ('LoginController', LoginController); LoginController. $ inject = ['$ location', '$ window', '$ http']; functie LoginController ($ location, $ window, $ http) {var vm = this; vm.login = login; (function initController () {$ window.localStorage.setItem ('token', '');}) (); functie login () {$ http ({url: '// localhost: 8082 / login', methode: "POST", data: {'gebruikersnaam': vm.username, 'wachtwoord': vm.password}}). dan (functie (antwoord) {if (antwoord.data) {var token = $ window.btoa (vm.username + ':' + vm.password); var userData = {gebruikersnaam: vm.username, authData: token} $ window .sessionStorage.setItem ('userData', JSON.stringify (userData)); $ http.defaults.headers.common ['Authorization'] = 'Basic' + token; $ location.path ('/');} else { alert ("Authenticatie mislukt.")}});};}}) ();

De controller roept de REST-service op door de gebruikersnaam en het wachtwoord door te geven. Na de succesvolle authenticatie worden de gebruikersnaam en het wachtwoord gecodeerd en wordt het gecodeerde token in de sessieopslag opgeslagen voor toekomstig gebruik.

Net als bij de login-component, bestaat de home-component ook uit twee bestanden, de home.view.html:

Je bent ingelogd !!

Uitloggen

en de home.controller.js:

(function () {'use strict'; angular .module ('app') .controller ('HomeController', HomeController); HomeController. $ inject = ['$ window', '$ http', '$ scope']; functie HomeController ($ window, $ http, $ scope) {var vm = this; vm.user = null; initController (); functie initController () {$ http ({url: '// localhost: 8082 / user', methode : "GET"}). Then (functie (antwoord) {vm.user = respons.data.name;}, functie (fout) {console.log (fout);});}; $ scope.logout = functie ( ) {$ window.sessionStorage.setItem ('userData', ''); $ http.defaults.headers.common ['Authorization'] = 'Basic';}}}) ();

De thuiscontroller vraagt ​​de gebruikersgegevens op door het Autorisatie koptekst. Onze REST-service retourneert de gebruikersgegevens alleen als het token geldig is.

Laten we nu installeren http-server voor het uitvoeren van de Angular-applicatie:

npm installeer http-server --save

Zodra dit is geïnstalleerd, kunnen we de hoofdmap van het project openen in de opdrachtprompt en de opdracht uitvoeren:

http-server -o

4.2. Angular versie 2, 4, 5 gebruiken

De index.html in versie 2 verschilt enigszins van de AngularJS-versie:

         System.import ('app'). Catch (function (err) {console.error (err);}); Bezig met laden... 

De main.ts is het belangrijkste toegangspunt van de applicatie. Het bootstraps de applicatiemodule en als resultaat laadt de browser de inlogpagina:

platformBrowserDynamic (). bootstrapModule (AppModule);

De app.routing.ts is verantwoordelijk voor de applicatie routing:

const appRoutes: Routes = [{pad: '', component: HomeComponent}, {pad: 'login', component: LoginComponent}, {pad: '**', redirectTo: ''}]; export const routing = RouterModule.forRoot (appRoutes);

De app.module.ts declareert de componenten en importeert de relevante modules:

@NgModule ({invoer: [BrowserModule, FormsModule, HttpModule, routing], declaraties: [AppComponent, HomeComponent, LoginComponent], bootstrap: [AppComponent]}) exportklasse AppModule {}

Omdat we een applicatie met één pagina maken, gaan we een rootcomponent maken die alle onderliggende componenten eraan toevoegt:

@Component ({selector: 'app-root', templateUrl: './app.component.html'}) exportklasse AppComponent {}

De app.component.html heeft alleen een label. De Angular gebruikt deze tag voor zijn locatierouteringsmechanisme.

Laten we nu de login-component en de bijbehorende sjabloon maken in login.component.ts:

@Component ({selector: 'login', templateUrl: './app/login/login.component.html'}) exportklasse LoginComponent implementeert OnInit {model: any = {}; constructor (privéroute: ActivatedRoute, privérouter: Router, privé http: Http) {} ngOnInit () {sessionStorage.setItem ('token', ''); } login () {let url = '// localhost: 8082 / login'; let result = this.http.post (url, {gebruikersnaam: this.model.username, wachtwoord: this.model.password}). map (res => res.json ()). subscribe (isValid => {if ( isValid) {sessionStorage.setItem ('token', btoa (this.model.username + ':' + this.model.password)); this.router.navigate (['']);} else {alert ("Authentication mislukt. ");}}); }}

Laten we tot slot eens kijken naar het login.component.html:

 Gebruikersnaam Gebruikersnaam is verplicht Wachtwoord Wachtwoord is vereist Inloggen 

4.3. Angular 6 gebruiken

Het Angular-team heeft enkele verbeteringen aangebracht in versie 6. Vanwege deze wijzigingen zal ons voorbeeld ook een beetje anders zijn dan andere versies. De enige wijziging die we in ons voorbeeld hebben met betrekking tot versie 6, is in het gedeelte voor serviceaanroepen.

In plaats van HttpModule, de versie 6 importeert HttpClientModule van@ angular / common / http.

Het serviceaanroepgedeelte zal ook een beetje verschillen van oudere versies:

deze.http.post(url, {gebruikersnaam: this.model.username, wachtwoord: this.model.password}). subscribe (isValid => {if (isValid) {sessionStorage.setItem ('token', btoa (this.model.username + ') : '+ this.model.password)); this.router.navigate ([' ']);} else {alert ("Authenticatie mislukt.")}});

5. Conclusie

We hebben geleerd hoe we een inlogpagina van Spring Security kunnen implementeren met Angular. Vanaf versie 4 kunnen we gebruik maken van het Angular CLI-project voor eenvoudig ontwikkelen en testen.

Zoals altijd zijn alle voorbeelden die we hier hebben besproken te vinden op het GitHub-project.


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