javascript
Angular 8 + Spring Boot 2.2:立即构建一个CRUD应用程序!
“我喜歡編寫身份驗證和授權代碼。” ?從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
如果您已經成為Java開發人員超過15年,那么您可能還記得什么時候有過多的Java Web框架。 它始于Struts和WebWork。 然后Tapestry,Wicket和JSF出現并倡導基于組件的框架的想法。 Spring MVC于2004年發布(與Flex 1.0和JSF 1.0同月發布),并在接下來的六年中成為Java Web框架的實際標準。
隨之而來的是AngularJS,每個人都開始將其UI架構轉移到JavaScript。 Angular 2是在2014年首次發布Spring Boot的同時宣布的,它花了幾年時間才發布,固化并成為可行的選擇。 這些天,我們將其稱為Angular,沒有版本號。 最近的幾個版本相當穩定,主要版本之間的升級路徑很流暢。
今天,我想向您展示如何使用Angular和Spring Boot的最新和最佳版本來構建應用程序。 Angular 8和Spring Boot 2.2都進行了性能改進,以改善開發人員的生活。
Angular 8有什么新功能?
Angular 8添加了差異加載,一個可選的Ivy Renderer和Bazel作為構建選項。 差異加載是CLI在構建已部署應用程序的一部分時構建兩個單獨的捆綁軟件的地方。 現代捆綁軟件可用于常綠的瀏覽器,而傳統捆綁軟件則包含舊瀏覽器所需的所有必需填充。
Ivy Renderer體積更小,更快,調試更簡單,類型檢查得到了改進,并且最重要的是向后兼容。
Spring Boot 2.2中有什么新功能?
Spring Boot在快速啟動的框架(例如Micronaut和Quarkus)中感到有些不適,并且也進行了許多性能改進。 現在默認情況下禁用JMX,禁用Hibernate的實體掃描,并且默認情況下啟用Bean的惰性初始化。 另外,通過在Spring Boot的@Configuration類中使用proxyBeanMethods=false減少了啟動時間和內存使用。 有關更多信息,請參見Spring Boot 2.2 Release Notes 。
如果您被這些框架的舊版本所困擾,則可能需要查看我之前的幾篇文章:
- 使用Angular 7.0和Spring Boot 2.1構建基本的CRUD應用
- 使用Angular 5.0和Spring Boot 2.0構建基本的CRUD應用
這篇文章介紹了如何構建一個簡單的CRUD應用程序,該應用程序顯示了一系列涼爽的汽車。 它允許您編輯汽車,并顯示GIPHY中與汽車名稱匹配的動畫gif。 您還將學習如何使用Okta的Spring Boot啟動程序和Angular SDK保護應用程序的安全。 下面是該應用完成時的屏幕截圖。
您將需要安裝Java 11和Node.js 10+才能完成本教程。
使用Spring Boot 2.2構建API
要開始使用Spring Boot 2.2,請轉到start.spring.io并創建一個使用Java 11(在更多選項下),Spring Boot版本2.2.0 M2和依賴項的新項目,以創建安全的API:JPA, H2,Rest Repository,Lombok,Okta和Web。
創建一個目錄來保存您的服務器和客戶端應用程序。 我叫我的okta-spring-boot-2-angular-8-example ,但是您可以隨便叫什么。
如果您希望應用程序運行而不是編寫代碼,則可以在GitHub上查看示例 ,或使用以下命令在本地克隆并運行。
git clone https://github.com/oktadeveloper/okta-spring-boot-2-angular-8-example.git cd okta-spring-boot-2-angular-8-example/client npm install ng serve & cd ../server ./mvnw spring-boot:run從start.spring.io下載demo.zip之后,展開它,然后將demo目錄復制到您的應用程序持有人目錄中。 將demo重命名為server 。 打開server/pom.xml并注釋掉Okta的Spring Boot啟動器上的依賴項。
<!--dependency><groupId>com.okta.spring</groupId><artifactId>okta-spring-boot-starter</artifactId><version>1.1.0</version> </dependency-->在您最喜歡的IDE中打開項目,并在src/main/java/com/okta/developer/demo目錄中創建Car.java類。 您可以使用Lombok的注釋來減少樣板代碼。
package com.okta.developer.demo;import lombok.*;import javax.persistence.Id; import javax.persistence.GeneratedValue; import javax.persistence.Entity;@Entity @Data @NoArgsConstructor public class Car {@Id @GeneratedValueprivate Long id;private @NonNull String name; }創建一個CarRepository類以對Car實體執行CRUD(創建,讀取,更新和刪除)。
package com.okta.developer.demo;import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.rest.core.annotation.RepositoryRestResource;@RepositoryRestResource interface CarRepository extends JpaRepository<Car, Long> { }將ApplicationRunner bean添加到DemoApplication類(在src/main/java/com/okta/developer/demo/DemoApplication.java ),并使用它向數據庫添加一些默認數據。
package com.okta.developer.demo;import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import java.util.stream.Stream;@SpringBootApplication public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@BeanApplicationRunner init(CarRepository repository) {return args -> {Stream.of("Ferrari", "Jaguar", "Porsche", "Lamborghini", "Bugatti","AMC Gremlin", "Triumph Stag", "Ford Pinto", "Yugo GV").forEach(name -> {Car car = new Car();car.setName(name);repository.save(car);});repository.findAll().forEach(System.out::println);};} }如果在添加此代碼后啟動應用程序(使用./mvnw spring-boot:run ),則會在啟動時看到控制臺中顯示的汽車列表。
Car(id=1, name=Ferrari) Car(id=2, name=Jaguar) Car(id=3, name=Porsche) Car(id=4, name=Lamborghini) Car(id=5, name=Bugatti) Car(id=6, name=AMC Gremlin) Car(id=7, name=Triumph Stag) Car(id=8, name=Ford Pinto) Car(id=9, name=Yugo GV)注意:如果看到Fatal error compiling: invalid target release: 11 ,這是因為您使用的是Java8。如果更改為使用Java 11,則該錯誤將消失。 如果您使用的是SDKMAN , 請先運行sdk install java 11.0.2-open然后運行sdk default java 11.0.2-open 。
添加一個CoolCarController類(在src/main/java/com/okta/developer/demo ),該類返回要在Angular客戶端中顯示的酷車列表。
package com.okta.developer.demo;import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Collection; import java.util.stream.Collectors;@RestController class CoolCarController {private CarRepository repository;public CoolCarController(CarRepository repository) {this.repository = repository;}@GetMapping("/cool-cars")public Collection<Car> coolCars() {return repository.findAll().stream().filter(this::isCool).collect(Collectors.toList());}private boolean isCool(Car car) {return !car.getName().equals("AMC Gremlin") &&!car.getName().equals("Triumph Stag") &&!car.getName().equals("Ford Pinto") &&!car.getName().equals("Yugo GV");} }如果重新啟動服務器,并使用瀏覽器或命令行客戶端訪問http://localhost:8080/cool-cars ,則應該看到過濾后的汽車列表。
$ http :8080/cool-cars HTTP/1.1 200 Content-Type: application/json;charset=UTF-8 Date: Tue, 07 May 2019 18:07:33 GMT Transfer-Encoding: chunked[{"id": 1,"name": "Ferrari"},{"id": 2,"name": "Jaguar"},{"id": 3,"name": "Porsche"},{"id": 4,"name": "Lamborghini"},{"id": 5,"name": "Bugatti"} ]使用Angular CLI創建客戶端
Angular CLI是一個命令行實用程序,可以為您生成Angular項目。 它不僅可以創建新項目,而且還可以生成代碼。 這是一個方便的工具,因為它還提供了一些命令,這些命令將生成和優化您的項目以進行生產。 它使用webpack在后臺進行構建。
安裝最新版本的Angular CLI(在撰寫本文時為v8.0.0-rc.3版本)。
npm i -g @angular/cli@v8.0.0-rc.3在您創建的傘形目錄中創建一個新項目。
ng new client --routing --style css --enable-ivy創建客戶端后,導航至其目錄,刪除.git ,然后安裝Angular Material。
cd client rm -rf .git # optional: .git won't be created if you don't have Git installed ng add @angular/material當提示您提供主題和其他選項時,請選擇默認值。
您將使用Angular Material的組件來改善UI的外觀,尤其是在手機上。 如果您想了解有關Angular Material的更多信息,請參見material.angular.io 。 它具有有關其各種組件以及如何使用它們的大量文檔。 右上角的油漆桶將允許您預覽可用的主題顏色。
使用Angular CLI構建汽車列表頁面
使用Angular CLI生成可以與Cool Cars API對話的汽車服務。
ng g s shared/car/car更新client/src/app/shared/car/car.service.ts以從服務器獲取汽車列表。
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs';@Injectable({providedIn: 'root' }) export class CarService {constructor(private http: HttpClient) {}getAll(): Observable<any> {return this.http.get('//localhost:8080/cool-cars');} }打開src/app/app.module.ts ,并將HttpClientModule添加為導入。
import { HttpClientModule } from '@angular/common/http';@NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,BrowserAnimationsModule,HttpClientModule],providers: [],bootstrap: [AppComponent] })生成car-list組件以顯示汽車列表。
ng g c car-list更新client/src/app/car-list/car-list.component.ts以使用CarService來獲取列表并在本地cars變量中設置值。
import { Component, OnInit } from '@angular/core'; import { CarService } from '../shared/car/car.service';@Component({selector: 'app-car-list',templateUrl: './car-list.component.html',styleUrls: ['./car-list.component.css'] }) export class CarListComponent implements OnInit {cars: Array<any>;constructor(private carService: CarService) { }ngOnInit() {this.carService.getAll().subscribe(data => {this.cars = data;});} }更新client/src/app/car-list/car-list.component.html以顯示汽車列表。
<h2>Car List</h2><div *ngFor="let car of cars">{{car.name}} </div>更新client/src/app/app.component.html以具有app-car-list元素。
<div style="text-align:center"><h1>Welcome to {{ title }}!</h1> </div><app-car-list></app-car-list> <router-outlet></router-outlet>使用ng serve -o啟動客戶端應用程序。 您現在還不會看到汽車清單,并且如果打開開發人員控制臺,就會明白原因。
發生此錯誤的原因是您尚未在服務器上啟用CORS(跨源資源共享)。
在服務器上啟用CORS
要在服務器上啟用CORS,添加@CrossOrigin注釋到CoolCarController (在server/src/main/java/com/okta/developer/demo/CoolCarController.java )。
import org.springframework.web.bind.annotation.CrossOrigin; ... @GetMapping("/cool-cars") @CrossOrigin(origins = "http://localhost:4200") public Collection<Car> coolCars() {return repository.findAll().stream().filter(this::isCool).collect(Collectors.toList()); }在Spring啟動版本2.1.4及以下,你還可以添加一個@CrossOrigin注釋您CarRepository 。 從Angular添加/刪除/編輯時,這將允許您與其端點進行通信。
import org.springframework.web.bind.annotation.CrossOrigin;@RepositoryRestResource @CrossOrigin(origins = "http://localhost:4200") interface CarRepository extends JpaRepository<Car, Long> { }但是,這在Spring Boot 2.2.0.M2中不再起作用 。 好消息是有解決方法。 您可以將CorsFilter bean添加到DemoApplication.java類中。 當您同時集成Spring Security時,這是必需的。 你只是早一點做。
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.core.Ordered; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; import java.util.Collections;...public class DemoApplication {// main() and init() methods@Beanpublic FilterRegistrationBean<CorsFilter> simpleCorsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = new CorsConfiguration();config.setAllowCredentials(true);config.setAllowedOrigins(Collections.singletonList("http://localhost:4200"));config.setAllowedMethods(Collections.singletonList("*"));config.setAllowedHeaders(Collections.singletonList("*"));source.registerCorsConfiguration("/**", config);FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));bean.setOrder(Ordered.HIGHEST_PRECEDENCE);return bean;} }重新啟動服務器,刷新客戶端,您應該在瀏覽器中看到汽車列表。
添加角材料
您已經安裝了Angular Material,要使用其組件,需要導入它們。 打開client/src/app/app.module.ts并添加動畫的導入,以及Material的工具欄,按鈕,輸入,列表和卡片布局。
import { MatButtonModule, MatCardModule, MatInputModule, MatListModule, MatToolbarModule } from '@angular/material';@NgModule({...imports: [BrowserModule,AppRoutingModule,BrowserAnimationsModule,HttpClientModule,MatButtonModule,MatCardModule,MatInputModule,MatListModule,MatToolbarModule],... })更新client/src/app/app.component.html以使用工具欄組件。
<mat-toolbar color="primary"><span>Welcome to {{title}}!</span> </mat-toolbar><app-car-list></app-car-list> <router-outlet></router-outlet>更新client/src/app/car-list/car-list.component.html以使用卡片布局和列表組件。
<mat-card><mat-card-title>Car List</mat-card-title><mat-card-content><mat-list><mat-list-item *ngFor="let car of cars"><img mat-list-avatar src="{{car.giphyUrl}}" alt="{{car.name}}"><h3 mat-line>{{car.name}}</h3></mat-list-item></mat-list></mat-card-content> </mat-card>如果使用ng serve運行客戶端并導航到http://localhost:4200 ,則會看到汽車列表,但沒有與之關聯的圖像。
使用Giphy添加動畫GIF
要將giphyUrl屬性添加到每輛汽車,請創建client/src/app/shared/giphy/giphy.service.ts并使用以下代碼填充。
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { map } from 'rxjs/operators';@Injectable({providedIn: 'root'}) export class GiphyService {// This is a Giphy API Key I created. Create your own at https://developers.giphy.com/dashboard/?create=true.giphyApi = '//api.giphy.com/v1/gifs/search?api_key=nOTRbUNMgD5mj4XowN2ERoPNudAkK6ft&limit=1&q=';constructor(public http: HttpClient) {}get(searchTerm) {const apiLink = this.giphyApi + searchTerm;return this.http.get(apiLink).pipe(map((response: any) => {if (response.data.length > 0) {return response.data[0].images.original.url;} else {return 'https://media.giphy.com/media/YaOxRsmrv9IeA/giphy.gif'; // dancing cat for 404}}));} }更新client/src/app/car-list/car-list.component.ts以在每輛汽車上設置giphyUrl屬性。
import { GiphyService } from '../shared/giphy/giphy.service';export class CarListComponent implements OnInit {cars: Array<any>;constructor(private carService: CarService, private giphyService: GiphyService) { }ngOnInit() {this.carService.getAll().subscribe(data => {this.cars = data;for (const car of this.cars) {this.giphyService.get(car.name).subscribe(url => car.giphyUrl = url);}});} }現在,您的瀏覽器將向您顯示汽車名稱列表,以及旁邊的頭像圖片。
向您的Angular應用添加編輯功能
列出汽車名稱和圖像很酷,但是當您與之互動時,它會更加有趣! 要添加編輯功能,請首先生成car-edit組件。
ng g c car-edit更新client/src/app/shared/car/car.service.ts以具有添加,移除和更新汽車的方法。 這些方法跟由提供的端點CarRepository及其@RepositoryRestResource注釋。
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs';@Injectable({providedIn: 'root'}) export class CarService {public API = '//localhost:8080';public CAR_API = this.API + '/cars';constructor(private http: HttpClient) {}getAll(): Observable<any> {return this.http.get(this.API + '/cool-cars');}get(id: string) {return this.http.get(this.CAR_API + '/' + id);}save(car: any): Observable<any> {let result: Observable<any>;if (car.href) {result = this.http.put(car.href, car);} else {result = this.http.post(this.CAR_API, car);}return result;}remove(href: string) {return this.http.delete(href);} }在client/src/app/car-list/car-list.component.html ,添加指向編輯組件的鏈接。 另外,在底部添加按鈕以添加新車。
<mat-card><mat-card-title>Car List</mat-card-title><mat-card-content><mat-list><mat-list-item *ngFor="let car of cars"><img mat-list-avatar src="{{car.giphyUrl}}" alt="{{car.name}}"><h3 mat-line><a mat-button [routerLink]="['/car-edit', car.id]">{{car.name}}</a></h3></mat-list-item></mat-list></mat-card-content><button mat-fab color="primary" [routerLink]="['/car-add']">Add</button> </mat-card>在client/src/app/app.module.ts ,導入FormsModule 。
import { FormsModule } from '@angular/forms';@NgModule({...imports: [...FormsModule],... })在client/src/app/app-routing.module.ts ,為CarListComponent和CarEditComponent添加路由。
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { CarListComponent } from './car-list/car-list.component'; import { CarEditComponent } from './car-edit/car-edit.component';const routes: Routes = [{ path: '', redirectTo: '/car-list', pathMatch: 'full' },{path: 'car-list',component: CarListComponent},{path: 'car-add',component: CarEditComponent},{path: 'car-edit/:id',component: CarEditComponent} ];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule] }) export class AppRoutingModule { }修改client/src/app/car-edit/car-edit.component.ts以從URL上傳遞的ID中獲取汽車信息,并添加保存和刪除方法。
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Subscription } from 'rxjs'; import { ActivatedRoute, Router } from '@angular/router'; import { CarService } from '../shared/car/car.service'; import { GiphyService } from '../shared/giphy/giphy.service'; import { NgForm } from '@angular/forms';@Component({selector: 'app-car-edit',templateUrl: './car-edit.component.html',styleUrls: ['./car-edit.component.css'] }) export class CarEditComponent implements OnInit, OnDestroy {car: any = {};sub: Subscription;constructor(private route: ActivatedRoute,private router: Router,private carService: CarService,private giphyService: GiphyService) {}ngOnInit() {this.sub = this.route.params.subscribe(params => {const id = params.id;if (id) {this.carService.get(id).subscribe((car: any) => {if (car) {this.car = car;this.car.href = car._links.self.href;this.giphyService.get(car.name).subscribe(url => car.giphyUrl = url);} else {console.log(`Car with id '${id}' not found, returning to list`);this.gotoList();}});}});}ngOnDestroy() {this.sub.unsubscribe();}gotoList() {this.router.navigate(['/car-list']);}save(form: NgForm) {this.carService.save(form).subscribe(result => {this.gotoList();}, error => console.error(error));}remove(href) {this.carService.remove(href).subscribe(result => {this.gotoList();}, error => console.error(error));} }更新client/src/app/car-edit/car-edit.component.htmlHTML以具有帶有汽車名稱的表單,并顯示來自Giphy的圖像。
<mat-card><form #carForm="ngForm" (ngSubmit)="save(carForm.value)"><mat-card-header><mat-card-title><h2>{{car.name ? 'Edit' : 'Add'}} Car</h2></mat-card-title></mat-card-header><mat-card-content><input type="hidden" name="href" [(ngModel)]="car.href"><mat-form-field><input matInput placeholder="Car Name" [(ngModel)]="car.name"required name="name" #name></mat-form-field></mat-card-content><mat-card-actions><button mat-raised-button color="primary" type="submit"[disabled]="!carForm.valid">Save</button><button mat-raised-button color="secondary" (click)="remove(car.href)"*ngIf="car.href" type="button">Delete</button><a mat-button routerLink="/car-list">Cancel</a></mat-card-actions><mat-card-footer><div class="giphy"><img src="{{car.giphyUrl}}" alt="{{car.name}}"></div></mat-card-footer></form> </mat-card>通過將以下CSS添加到client/src/app/car-edit/car-edit.component.css ,在圖像周圍添加一些填充。
.giphy {margin: 10px; }修改client/src/app/app.component.html并刪除<app-car-list></app-car-list> 。
<mat-toolbar color="primary"><span>Welcome to {{title}}!</span> </mat-toolbar><router-outlet></router-outlet>進行所有這些更改之后,您應該可以添加,編輯或刪除任何汽車。 下面的屏幕快照顯示了帶有添加按鈕的列表。
以下屏幕截圖顯示了編輯已添加的汽車的外觀。
將OIDC身份驗證添加到您的Spring Boot + Angular App中
使用OIDC添加身份驗證是一個不錯的功能,可以添加到此應用程序中。 如果您想添加審核或個性化您的應用程序(例如,使用評分功能),則知道此人是誰會很方便。
Spring Security + OIDC
在服務器端,您可以使用Okta的Spring Boot Starter來鎖定一切,它利用了Spring Security及其OIDC支持。 打開server/pom.xml并取消注釋Okta Spring Boot啟動器。
<dependency><groupId>com.okta.spring</groupId><artifactId>okta-spring-boot-starter</artifactId><version>1.1.0</version> </dependency>現在,您需要配置服務器以使用Okta進行身份驗證。 為此,您需要在Okta中創建OIDC應用。
在Okta中創建OIDC應用
登錄到您的1563開發者帳戶(或者注冊 ,如果你沒有一個帳戶)并導航到應用程序 > 添加應用程序 。 單擊“ 單頁應用程序” ,再單擊“ 下一步” ,然后為該應用程序命名。 將所有http://localhost:8080實例更改為http://localhost:4200 ,然后單擊完成 。
您將在頁面底部看到一個客戶端ID。 將它和issuer屬性添加到server/src/main/resources/application.properties 。
okta.oauth2.client-id={yourClientId} okta.oauth2.issuer=https://{yourOktaDomain}/oauth2/default創建server/src/main/java/com/okta/developer/demo/SecurityConfiguration.java以將您的Spring Boot應用配置為資源服務器。
package com.okta.developer.demo;import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().oauth2ResourceServer().jwt();} }進行這些更改之后,您應該能夠重新啟動應用程序,并在嘗試導航到http://localhost:8080時看到錯誤。
注意:您可以通過將http://localhost:8080/login/oauth2/code/okta為應用程序的重定向URI來解決此錯誤,但這不能解決問題。 如果您想通過Spring Boot支持OIDC登錄,則需要注冊一個Web應用程序(而不是SPA),并在application.properties包含一個客戶端密碼。 這不是本教程中的必要步驟。
現在您的服務器已被鎖定,您需要配置客戶端以使用訪問令牌與之對話。 這就是Okta的Angular SDK派上用場的地方。
Okta的角度支撐
Okta Angular SDK是Okta Auth JS的包裝,后者基于OIDC。 可以在GitHub上找到有關Okta的Angular庫的更多信息。
為了簡化Angular SDK的安裝和配置,我們創建了一個@ oktadev / schematics項目,該項目可以為您完成所有工作。 您可以在“ 使用角度示意圖簡化生活”中閱讀有關@ oktadev / schematics如何工作的更多信息。
在安裝它之前,最好將您的項目檢查到源代碼管理中。 如果未安裝Git,則可以將項目復制到另一個位置作為備份。 如果確實安裝了Git,請從項目的根目錄中運行以下命令。
git init git add . git commit -m "Initialize project"要安裝和配置Okta的Angular SDK,請在client目錄中運行以下命令:
ng add @oktadev/schematics --issuer=https://{yourOktaDomain}/oauth2/default --clientId={yourClientId}該命令將:
- 安裝@okta/okta-angular
- 在auth-routing.module.ts為您的應用配置Okta的Angular SDK
- 將isAuthenticated邏輯添加到app.component.ts
- 添加帶有登錄和注銷按鈕的HomeComponent
- 使用到/home的默認路由和/implicit/callback路由配置路由
- 添加一個HttpInterceptor ,它向localhost請求添加一個帶有訪問令牌的Authorization標頭
修改client/src/app/app.component.html以使用Material組件并具有注銷按鈕。
<mat-toolbar color="primary"><span>Welcome to {{title}}!</span><span class="toolbar-spacer"></span><button mat-raised-button color="accent" *ngIf="isAuthenticated"(click)="oktaAuth.logout()" [routerLink]="['/home']">Logout</button> </mat-toolbar><router-outlet></router-outlet>您可能會注意到toolbar-spacer類存在跨度。 要使此功能按預期工作,請在client/src/app/app.component.css添加一個toolbar-spacer規則。
.toolbar-spacer {flex: 1 1 auto; }然后更新client/src/app/home/home.component.html以使用Angular Material并鏈接到Car List。
<mat-card><mat-card-content><button mat-raised-button color="accent" *ngIf="!isAuthenticated"(click)="oktaAuth.loginRedirect()">Login</button><button mat-raised-button color="accent" *ngIf="isAuthenticated"[routerLink]="['/car-list']">Car List</button></mat-card-content> </mat-card>由于您使用的是HomeComponent Material組件,該組件由新添加的client/src/app/auth-routing.module.ts ,因此需要導入MatCardModule 。
import { MatCardModule } from '@angular/material';@NgModule({...imports: [...MatCardModule],... })要使其內容底部沒有底邊框,請通過將以下內容添加到client/src/styles.css來使<mat-card>元素填充屏幕。
mat-card {height: 100vh; }現在,如果您重新啟動客戶端,一切都應該工作。 不幸的是,這不是因為Ivy尚未實現CommonJS / UMD支持 。 解決方法是,您可以修改tsconfig.app.json以禁用Ivy。
"angularCompilerOptions": {"enableIvy": false }停止并重新啟動ng serve過程。 打開瀏覽器到http://localhost:4200 。
單擊登錄按鈕。 如果一切配置正確,您將被重定向到Okta登錄。
輸入有效的憑據,您應該被重定向回您的應用程序。 慶祝一切成功! 🎉
了解有關Spring Boot和Angular的更多信息
跟上快速移動的框架(如Spring Boot和Angular)可能很難。 這篇文章旨在為您提供最新版本的快速入門。 有關Angular 8的特定更改,請參閱Angular團隊針對8.0版和Ivy的計劃 。 對于Spring Boot,請參閱其2.2發行說明 。
您可以在oktadeveloper / okta-spring-boot-2-angular-8-example上的GitHub上看到本教程中開發的應用程序的完整源代碼。
這個博客有大量的Spring Boot和Angular教程。 這是我的最愛:
- 使用Angular和Electron構建桌面應用程序
- 將您的Spring Boot應用程序遷移到最新和最新的Spring Security和OAuth 2.0
- Java 11,Spring Boot和JavaScript中的i18n
- 為Angular應用程序建立安全登錄
- 使用Spring WebFlux構建反應性API
如有任何疑問,請隨時在下面發表評論,或在我們的Okta開發者論壇上向我們提問。 別忘了在Twitter和YouTube 上關注我們!
“ Angular 8 + Spring Boot 2.2:今天就構建一個CRUD應用程序!” 最初于2019年5月13日發布在Okta開發人員博客上。
“我喜歡編寫身份驗證和授權代碼。” ?從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
翻譯自: https://www.javacodegeeks.com/2019/05/angular-spring-boot-build-crud-app-today.html
總結
以上是生活随笔為你收集整理的Angular 8 + Spring Boot 2.2:立即构建一个CRUD应用程序!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾达设置网址(腾达无线网设置网址)
- 下一篇: 本命年佩戴什么饰品比较好?(本命年转运和