Angular 2 Базовая аутентификация не работает

Я пытаюсь подключиться/выполнить запрос POST в API с помощью Angular2, это очень простой API с базовым паролем аутентификации. При отключении пароля на api все работает так, как ожидалось. Но когда я включаю базовую аутентификацию, Angular больше не может подключаться к API. В Почтальоне все работает. Я пробовал следующее без успеха.

У меня есть два заголовка "Content-Type" и "Authorization"

headers.append("Content-Type", "application/x-www-form-urlencoded");

Я пробовал эти два заголовка.

headers.append("Authorization", "Basic " + btoa(Username + ":" + Password)); 
headers.append("Authorization", "Basic VXNlcm5hbWU6UGFzc3dvcmQ=");

Единственное, что я могу найти, это то, что в заголовках запроса RAW существует только строка с именами заголовков, но значения отсутствуют:

Access-Control-Request-Headers: authorization, content-type

Необработанные заголовки:

#Request Headers
OPTIONS /shipment HTTP/1.1
Host: api.example.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Access-Control-Request-Headers: authorization, content-type
Accept: */*
Referer: http://localhost:4200/address
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,nl;q=0.6

Надеюсь, кто-то может помочь

Ответы

Ответ 1

Упрощенная версия для добавления пользовательских заголовков в ваш запрос:

import {Injectable} from '@angular/core';
import {Http, Headers} from '@angular/http';

@Injectable()
export class ApiService {

   constructor(private _http: Http) {}

   call(url): Observable<any> {
      let username: string = 'username';
      let password: string = 'password';
      let headers: Headers = new Headers();
      headers.append("Authorization", "Basic " + btoa(username + ":" + password)); 
      headers.append("Content-Type", "application/x-www-form-urlencoded");
      return this._http.post(url, data, {headers: headers})
    }
}

Трудно определить, где вы поступили не так, потому что отсутствует код действительного вызова http. Но этот пример должен работать для вас.

Ответ 2

У меня была такая же проблема в моем приложении.

Как вы видите, запрос, который отправлен, не является POST, а OPTION (предварительная проверка)

https://developer.mozilla.org/fr/docs/HTTP/Access_control_CORS

Вы должны разрешить запрос OPTIONS на стороне вашего API. Если у вас есть приложение Spring, вы можете просто добавить это в Spring Конфигурация безопасности:

    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                **.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()**
(..)

}

В моем случае это работает

Ответ 3

Это решило мои проблемы:
Angular2 http post - как отправить заголовок авторизации?

Ok. Я нашел проблему.

Он не был на стороне Angular. Честно говоря, проблем не было.

Причина, по которой мне не удалось выполнить мой запрос, было то, что мое приложение-сервер неправильно обрабатывал запрос OPTIONS.

Почему OPTIONS, а не POST? Мое серверное приложение находится на другом хосте, а затем в интерфейсе. Из-за CORS мой браузер конвертировал POST в OPTION: http://restlet.com/blog/2015/12/15/understanding-and-using-cors/

С помощью этого ответа: Автономный Spring OAuth2 Сервер авторизации JWT + CORS

Я применил правильный фильтр в своем серверном приложении.

Спасибо @Supamiu - человек, который мне пальцы, что я вообще не отправляю POST.

Ответ 4

jrcastillo предложил другой вариант здесь

Я потратил столько часов, пытаясь исправить это, и этот один лайнер решил мою проблему.

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}

В конце концов я был более конкретным, так как это вызвало мой путь /login, поэтому я сделал следующее:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.OPTIONS, "/api/**");
}

Ответ 5

Проблема с серверным сервером. Любой браузер отправляет запрос предполетного запроса, делающий запрос на перекрестный поиск. Бэкэнд-сервер в этом случае не обрабатывает запрос предварительной проверки. Попробуйте выполнить конфигурацию cors на сервере backend. Это решит эту проблему.