@dspies Привет, я интегрировал мое угловое приложение с пружиной, поэтому все остальные вызовы находятся в одной области.
аюсь сделать запрос POST черезабсолютный URL к Spring (Basic аутентификация) защищенного Rest API.
Прочитав, что Angular пропускает вставкуX-XSRF-ЗНАК в заголовок запроса автоматически для абсолютных URL, я попытался реализоватьHttpInterceptor добавить токен в.
В моем оригинале/войти в систему POST запрос, я создаю необходимыйавторизация: базовая заголовок, чтобы гарантировать, что Spring аутентифицирует запрос.
Возвращенный заголовок ответа содержит ожидаемыйSet-Cookie маркер:Set-Cookie:XSRF-TOKEN=4e4a087b-4184-43de-81b0-e37ef953d755; Path=/
Тем не менее, в моем собственном классе перехватчика, когда я пытаюсь получить токен из введенногоHttpXsrfTokenExtractor для следующего запроса он возвращаетзначение NULL.
Вот код для моего класса перехватчика:
import {Injectable, Inject} from '@angular/core';
import { Observable } from 'rxjs/Rx';
import {HttpInterceptor, HttpXsrfTokenExtractor, HttpRequest, HttpHandler,
HttpEvent} from '@angular/common/http';
@Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let requestMethod: string = req.method;
requestMethod = requestMethod.toLowerCase();
if (requestMethod && (requestMethod === 'post' || requestMethod === 'delete' || requestMethod === 'put' )) {
const headerName = 'X-XSRF-TOKEN';
let token = this.tokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, token) });
}
}
return next.handle(req);
}
}
tokenExtractor.getToken () возвращает ноль в приведенном выше коде. Я ожидал, что он вернет токен из заголовка ответа Spring (Set-Cookie) моего предыдущего/войти в систему запрос.
Я прочитал этот связанный пост для создания перехватчика:
Angular4 httpclient csrf не отправляет x-xsrf-токен
Но я не смог найти много документации для HttpXsrfTokenExtractor, кроме этого:
https://angular.io/api/common/http/HttpXsrfTokenExtractor
Вопрос: почемуHttpXsrfTokenExtractor.getToken () возвращать ноль?
Кроме того, я добавил класс перехватчика в качестве поставщика кapp.module.
Вот мой app.module.ts:
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { LocationStrategy, HashLocationStrategy, APP_BASE_HREF } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AlertModule } from 'ng2-bootstrap';
import { routing, appRouterProviders } from './app.routing';
import { HttpXsrfInterceptor } from './httpxrsf.interceptor';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './registration/register.component';
import { HomeComponent } from './home/home.component';
@NgModule({
declarations: [AppComponent,
LoginComponent,
RegisterComponent,
HomeComponent],
imports: [BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
HttpClientXsrfModule, // Adds xsrf support
AlertModule.forRoot(),
routing],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
appRouterProviders,
[{provide: APP_BASE_HREF, useValue: '/'}],
[{provide: LocationStrategy, useClass: HashLocationStrategy}],
[{provide: HTTP_INTERCEPTORS, useClass: HttpXsrfInterceptor, multi: true }]
],
bootstrap: [AppComponent]
})
export class AppModule {}
Еще одна вещь, которую стоит отметить, это то, что я запускаю свой угловой интерфейс на Node.js излокальный: 3000 и мой весенний отдых отлокальный: 8080, Они находятся на разных портах, и поэтому причина для выполнения http-запросов сабсолютные URL, Будет ли браузер предотвращатьSet-Cookie работает, когда приходит ответ на запрос в другом домене?
Могу ли я пропустить что-нибудь еще?
Спасибо за любую помощь.
----------------------------------------------
[Обновлено 7 января 2018 года]
FIX
я используюWebpack Dev Server обслуживать Угловой кодекс. Я обошел проблему, настроивполномочие для URL-адресов, которые указывают на мой бэкэнд Rest API.
Это означает, что все запросы, сделанные из браузера, теперь только к dev-серверу в порту3000даже для вызовов API остальных.
Когдасервер разработки веб-пакетов видит любые URL-адреса запроса с настроенным шаблоном (например, g / api / ...), он заменяет вызовы на внутренний сервер наHTTP: // локальный: 8080 (в моем случае).
Это то, что я добавил вdevServer раздел моегоwebpack.dev.js файл:
proxy: {
'/api': {
'target': 'http://localhost:8080',
'pathRewrite': {'^/api' : ''}
//Omits /api from the actual request. E.g. http://localhost:8080/api/adduser -> http://localhost:8080/adduser
}
}
С этой настройкой я больше не делаю междоменных (кросс-исходных) запросов из кода Angular или больше не использую абсолютные URL. Это сильно упрощает ситуацию, так как я больше не сражаюсь с механизмом Angular XSRF (CSRF). Это просто работает по умолчанию. Мне также не нужно использоватьHttpInterceptor вручную вставитьX-XSRF-ЗНАК в любом.
Дополнительным преимуществом настройки прокси-сервера dev является то, что клиентские запросы больше не являются абсолютными, поэтому мне не нужно менять все вызовы Rest API для производства.
Я надеюсь, что это полезно для тех, кто страдает той же проблемой / пониманием.
Документация прокси сервера разработки Webpack ref:
https://webpack.js.org/configuration/dev-server/#devserver-proxy