Spring Cloud - Добавление угловых 4

Spring Cloud - Добавление угловых 4

1. обзор

В нашей последней статье о Spring Cloud мы добавили поддержкуZipkin в наше приложение. В этой статье мы собираемся добавить интерфейсное приложение в наш стек.

До сих пор мы полностью работали над серверной частью для создания нашего облачного приложения. Но что хорошего в веб-приложении, если в нем нет пользовательского интерфейса? В этой статье мы собираемся решить эту проблему, интегрировав одностраничное приложение в наш проект.

Мы будем писать это приложение, используяAngular иBootstrap. Стиль кода Angular 4 очень напоминает кодирование приложения Spring, которое является естественным переходом для разработчика Spring! В то время как код переднего плана будет использовать Angular, содержание этой статьи можно легко распространить на любой интерфейс переднего плана с минимальными усилиями.

В этой статье мы собираемся создать приложение Angular 4 и подключить его к нашим облачным сервисам. Мы покажем, как интегрировать вход в систему между SPA и Spring Security. Мы также покажем, как получить доступ к данным нашего приложения, используя поддержку Angular для HTTP-связи.

2. Изменения шлюза

Создав интерфейс, мы собираемся перейти к авторизации на основе форм и защищенным частям пользовательского интерфейса для привилегированных пользователей. Это требует внесения изменений в конфигурацию безопасности нашего шлюза.

2.1. ОбновитьHttpSecurity

Во-первых, давайте обновим методconfigure(HttpSecurity http) в нашем классе шлюзаSecurityConfig.java:

@Override
protected void configure(HttpSecurity http) {
    http
      .formLogin()
      .defaultSuccessUrl("/home/index.html", true)
      .and()
    .authorizeRequests()
      .antMatchers("/book-service/**", "/rating-service/**", "/login*", "/")
      .permitAll()
      .antMatchers("/eureka/**").hasRole("ADMIN")
      .anyRequest().authenticated()
      .and()
    .logout()
      .and()
    .csrf().disable();
}

Во-первых, мы добавляем URL-адрес успеха по умолчанию, чтобы указать на/home/index.html, поскольку именно здесь будет жить наше приложение Angular. Затем мы настраиваем сопоставители муравьев, чтобы разрешить любой запрос через шлюз, кроме ресурсовEureka. Это позволит делегировать все проверки безопасности внутренним службам.

Затем мы удалили URL успеха выхода из системы, так как перенаправление по умолчанию обратно на страницу входа будет работать нормально.

2.2. Добавить основную конечную точку

Затем давайте добавим конечную точку для возврата аутентифицированного пользователя. Это будет использоваться в нашем приложении Angular для входа в систему и определения ролей, которые выполняет наш пользователь. Это поможет нам контролировать действия, которые они могут выполнять на нашем сайте.

В проекте шлюза добавьте классAuthenticationController:

@RestController
public class AuthenticationController {

    @GetMapping("/me")
    public Principal getMyUser(Principal principal) {
        return principal;
    }
}

Контроллер возвращает вызывающий в данный момент пользовательский объект вызывающей стороне. Это дает нам всю информацию, необходимую нам для управления нашим приложением Angular.

2.3. Добавить целевую страницу

Давайте добавим очень простую целевую страницу, чтобы пользователи видели что-то, когда заходят в корень нашего приложения.

Вsrc/main/resources/static, добавим файлindex.html со ссылкой на страницу входа:




    
    Book Rater Landing


    

Book Rater

So many great things about the books

Login

3. Angular CLI и стартовый проект

Перед запуском нового проекта Angular обязательно установите последние версииNode.js and npm.

3.1. Установите Angular CLI

Для начала нам нужно будет использоватьnpm для загрузки и установки интерфейса командной строки Angular. Откройте терминал и запустите:

npm install -g @angular/cli

Это загрузит и установит CLI глобально.

3.2. Установить новый проект

Находясь в терминале, перейдите к проекту шлюза и перейдите в папку gateway / src / main. Создайте каталог под названием «angular» и перейдите к нему. Отсюда бегите:

ng new ui

Потерпи; интерфейс командной строки создает новый проект и загружает все зависимости JavaScript с помощью npm. Это не редкость, когда этот процесс занимает много минут.

Командаng является ярлыком для Angular CLI, параметрnew указывает этому CLI создать новый проект, а командаui дает нашему проекту имя.

3.3. Запустить проект

После завершения командыnew. Перейдите в папкуui, которая была создана и запущена:

ng serve

После сборки проекта перейдите кhttp://localhost:4200. Мы должны увидеть это в браузере:

image

Поздравляем! Мы только что создали приложение Angular!

3.4. Установить Bootstrap

Давайте использовать npm для установки начальной загрузки. Из каталога пользовательского интерфейса выполните эту команду:

npm install [email protected] --save

Это загрузит загрузчик в папку node_modules.

В каталогеui откройте файл.angular-cli.json. Это файл, который настраивает некоторые свойства нашего проекта. Найдите свойствоapps > styles и добавьте расположение файла нашего CSS-класса Bootstrap:

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

Это проинструктирует Angular включить Bootstrap в скомпилированный файл CSS, созданный с помощью проекта.

3.5. Установите каталог вывода сборки

Далее нам нужно указать Angular, куда поместить файлы сборки, чтобы наше приложение весенней загрузки могло их обслуживать. Spring Boot может обслуживать файлы из двух мест в папке ресурсов:

  • src/main/resources/static

  • src/main/resource/public

Поскольку мы уже используем статическую папку для обслуживания некоторых ресурсов для Eureka, а Angular удаляет эту папку при каждом запуске сборки, давайте соберем наше приложение Angular в общую папку.

Снова откройте файл.angular-cli.json и найдите свойствоapps > outDir. Обновите этоstring:

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

Если проект Angular находится в src / main / angular / ui, он будет построен в папке src / main / resources / public. Если приложение находится в другой папке, эту строку необходимо изменить, чтобы правильно указать местоположение.

3.6. Автоматизируйте сборку с помощью Maven

Наконец, мы настроим автоматическую сборку, которая будет выполняться при компиляции нашего кода. Эта задача муравья будет запускать задачу сборки Angular CLI всякий раз, когда запускается «mvn compile». Добавьте этот шаг в файл POM.xml шлюза, чтобы каждый раз при компиляции получать последние изменения пользовательского интерфейса:


    maven-antrun-plugin
    
        
            generate-resources
            
                
                    
                        
                        
                        
                    
                    
                        
                        
                    
                
            
            
                run
            
        
    

Мы должны отметить, что эта настройка требует, чтобы Angular CLI был доступен на пути к классам. Отправка этого сценария в среду, в которой нет этой зависимости, приведет к сбоям сборки.

Теперь приступим к созданию приложения Angular!

4. угловатый

В этом разделе руководства мы создадим механизм аутентификации на нашей странице. Мы используем базовую аутентификацию и следуем простой процедуре, чтобы заставить ее работать.

У пользователей есть форма входа в систему, где они могут ввести свое имя пользователя и пароль.

Затем мы используем их учетные данные для создания токена аутентификации base64 и запрашиваем конечную точку“/me”. Конечная точка возвращает объектPrincipal, содержащий роли этого пользователя.

Наконец, мы будем хранить учетные данные и принципал на клиенте для использования в последующих запросах.

Посмотрим, как это делается!

4.1. шаблон

В проекте шлюза перейдите кsrc/main/angular/ui/src/app и откройте файлapp.component.html. Это первый шаблон, который загружается в Angular, и именно туда будут заходить наши пользователи после входа в систему.

Здесь мы собираемся добавить код для отображения панели навигации с формой входа:



Book Rater App

Anyone can view the books.

Users can view and create ratings

Admins can do anything!

Этот код устанавливает панель навигации с классами Bootstrap. В панель встроена встроенная форма входа. Angular использует эту разметку для динамического взаимодействия с JavaScript для визуализации различных частей страницы и управления такими вещами, как отправка форм.

Такие утверждения, как(ngSubmit)=”onLogin(f)”, просто указывают на то, что при отправке формы вызовите метод“onLogin(f)” и передайте форму этой функции. В divjumbotron у нас есть теги абзацев, которые будут отображаться динамически в зависимости от состояния нашего основного объекта.

Затем давайте создадим код файла Typescript, который будет поддерживать этот шаблон.

4.2. Машинопись

Из этого же каталога откройте файл app.component.ts. В этом файле мы добавим все свойства и методы машинописного текста, необходимые для работы нашего шаблона:

import {Component} from "@angular/core";
import {Principal} from "./principal";
import {Response} from "@angular/http";
import {Book} from "./book";
import {HttpService} from "./http.service";

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    selectedBook: Book = null;
    principal: Principal = new Principal(false, []);
    loginFailed: boolean = false;

    constructor(private httpService: HttpService){}

    ngOnInit(): void {
        this.httpService.me()
          .subscribe((response: Response) => {
              let principalJson = response.json();
              this.principal = new Principal(principalJson.authenticated,
              principalJson.authorities);
          }, (error) => {
              console.log(error);
        });
    }

    onLogout() {
        this.httpService.logout()
          .subscribe((response: Response) => {
              if (response.status === 200) {
                  this.loginFailed = false;
                  this.principal = new Principal(false, []);
                  window.location.replace(response.url);
              }
           }, (error) => {
               console.log(error);
       });
    }
}

Этот класс подключается к методу жизненного цикла AngularngOnInit(). В этом методе мы вызываем конечную точку/me, чтобы получить текущую роль и состояние пользователя. Это определяет, что пользователь видит на главной странице. Этот метод будет запускаться всякий раз, когда будет создан этот компонент, и это отличное время, чтобы проверить свойства пользователя на предмет разрешений в нашем приложении.

У нас также есть методonLogout(), который выводит нашего пользователя из системы и восстанавливает состояние этой страницы до исходных настроек.

Но здесь творится какое-то волшебство. СвойствоhttpService, объявленное в конструкторе. Angular вводит это свойство в наш класс во время выполнения. Angular управляет единичными экземплярами классов обслуживания и внедряет их, используя инъекцию конструктора, как Spring!

Далее нам нужно определить классHttpService.

4.3. HttpServiceс

В том же каталоге создайте файл с именем“http.service.ts”. В этом файле добавьте этот код для поддержки методов входа и выхода:

import {Injectable} from "@angular/core";
import {Observable} from "rxjs";
import {Response, Http, Headers, RequestOptions} from "@angular/http";
import {Book} from "./book";
import {Rating} from "./rating";

@Injectable()
export class HttpService {

    constructor(private http: Http) { }

    me(): Observable {
        return this.http.get("/me", this.makeOptions())
    }

    logout(): Observable {
        return this.http.post("/logout", '', this.makeOptions())
    }

    private makeOptions(): RequestOptions {
        let headers = new Headers({'Content-Type': 'application/json'});
        return new RequestOptions({headers: headers});
    }
}

В этом классе мы внедряем другую зависимость с помощью конструкции DI Angular. На этот раз это классHttp. Этот класс обрабатывает все HTTP-коммуникации и предоставляется нам фреймворком.

Каждый из этих методов выполняет HTTP-запрос с использованием HTTP-библиотеки angular. Каждый запрос также указывает тип содержимого в заголовках.

Теперь нам нужно сделать еще одну вещь, чтобы зарегистрироватьHttpService в системе внедрения зависимостей. Откройте файлapp.module.ts и найдите свойство провайдеров. ДобавьтеHttpService в этот массив. Результат должен выглядеть так:

providers: [HttpService],

4.4. Добавить участника

Затем давайте добавим наш объект Principal DTO в наш код Typescript. В том же каталоге добавьте файл с именем «Principal.ts» и добавьте этот код:

export class Principal {
    public authenticated: boolean;
    public authorities: Authority[] = [];
    public credentials: any;

    constructor(authenticated: boolean, authorities: any[], credentials: any) {
        this.authenticated = authenticated;
        authorities.map(
          auth => this.authorities.push(new Authority(auth.authority)))
        this.credentials = credentials;
  }

    isAdmin() {
        return this.authorities.some(
          (auth: Authority) => auth.authority.indexOf('ADMIN') > -1)
    }
}

export class Authority {
    public authority: String;

    constructor(authority: String) {
        this.authority = authority;
    }
}

Мы добавили классPrincipal и классAuthority. Это два класса DTO, очень похожие на POJO в приложении Spring. Из-за этого нам не нужно регистрировать эти классы в системе DI в угловых.

Затем давайте настроим правило перенаправления для перенаправления неизвестных запросов в корень нашего приложения.

4.5. 404 Обработка

Давайте вернемся к коду Java для службы шлюза. В класс, где находитсяGatewayApplication, добавьте новый класс с именемErrorPageConfig:

@Component
public class ErrorPageConfig implements ErrorPageRegistrar {

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

}

Этот класс идентифицирует любой ответ 404 и перенаправит пользователя на“/home/index.html”. В одностраничном приложении мы обрабатываем весь трафик, не поступающий на выделенный ресурс, поскольку клиент должен обрабатывать все маршруты, по которым можно перемещаться.

Теперь мы готовы запустить это приложение и посмотреть, что мы создали!

4.6. Сборка и просмотр

Теперь запустите «mvn compile» из папки шлюза. Это скомпилирует исходный код Java и создаст приложение Angular в общей папке. Давайте запустим другие облачные приложения:config,discovery иzipkin. Затем запустите проект шлюза. Когда служба запустится, перейдите кhttp://localhost:8080, чтобы увидеть наше приложение. Мы должны увидеть что-то вроде этого:

image

Затем давайте перейдем по ссылке на страницу входа:

image

Войдите, используя учетные данные пользователя / пароля. Нажмите «Войти», и мы должны быть перенаправлены в /home/index.html, где загружается наше одностраничное приложение.

image

Похоже, нашjumbotron указывает, что мы вошли в систему как пользователь! Теперь выйдите из системы, щелкнув ссылку в правом верхнем углу, и на этот раз войдите, используя учетные данныеadmin/admin.

image

Выглядит хорошо! Теперь мы вошли в систему как администратор.

5. Заключение

В этой статье мы увидели, как легко интегрировать одностраничное приложение в нашу облачную систему. Мы взяли современный фреймворк и интегрировали рабочую конфигурацию безопасности в наше приложение.

Используя эти примеры, попробуйте написать код для вызоваbook-service илиrating-service. Поскольку теперь у нас есть примеры выполнения HTTP-вызовов и передачи данных в шаблоны, это должно быть относительно просто.

Если вы хотите увидеть, как остальная часть сайта построена, как всегда, вы можете найти исходный кодover on Github.