Как выйти из Angular / Spring по POST - PullRequest
0 голосов
/ 02 июля 2019

Я хочу выйти из системы Angular с использованием метода POST, вот мой код:

  logout() {
    const url = 'http://localhost:8181/user/logout';
    const xToken = localStorage.getItem('xAuthToken');
    const basicHeader = 'Basic ' + localStorage.getItem('credentials');
    const headers = new Headers({
      'x-auth-token': xToken,
      'Authorization': basicHeader
    });
    // return this.http.get(url, { headers: headers }); // This will work
    return this.http.post(url, { headers: headers }); // This will generate error
  }

И вот мой бэкэнд:

@RequestMapping("/user/logout")
public ResponseEntity<String> logout(){
    SecurityContextHolder.clearContext();
    return new ResponseEntity<String>("Logout Successfully!", HttpStatus.OK);
}

Странная вещь заключается в том, что приведенный выше код работает сthis.http.get но сгенерирует ошибку ниже this.http.post.И вот ошибка с this.http.post:

POST http://localhost:8181/user/logout 401

Если я изменяю код с помощью HttpClient, например:

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

@Injectable({
  providedIn: 'root'
})
export class LoginService {

  constructor(private http: HttpClient) {
  }

  sendCredential(username: string, password: string) {
    let url = "http://localhost:8181/token";
    let encodedCredentials = btoa(username + ":" + password);// encode in base64 to send a token
    let basicHeader = "Basic " + encodedCredentials;
    let headers = new Headers({
      'Content-Type': 'application/x-www-form-urlencoded',
      'Authorization': basicHeader
    })
    // send credential method when login component
    return this.http.get(url, { headers: headers }); // Error at this line
  }

  checkSession() {
    const url = 'http://localhost:8181/checkSession';
    const xToken = localStorage.getItem('xAuthToken');
    const basicHeader = 'Basic ' + localStorage.getItem('credentials');
    const headers = new Headers({
      'x-auth-token': xToken,
      'Authorization': basicHeader
    });
    return this.http.get(url, { headers: headers }); // Error at this line
  }

  logout() {
    const url = 'http://localhost:8181/user/logout';
    const xToken = localStorage.getItem('xAuthToken');
    const basicHeader = 'Basic ' + localStorage.getItem('credentials');
    const headers = new Headers({
      'x-auth-token': xToken,
      'Authorization': basicHeader
    });

    return this.http.get(url, { headers: headers }); // Error at this line
  }
}

Тогда я получаю сообщение об ошибке:

(property) headers?: HttpHeaders | {
    [header: string]: string | string[];
}
Type 'Headers' is not assignable to type 'HttpHeaders | { [header: string]: string | string[]; }'.
  Type 'Headers' is not assignable to type '{ [header: string]: string | string[]; }'.
    Index signature is missing in type 'Headers'.ts(2322)
http.d.ts(1086, 9): The expected type comes from property 'headers' which is declared here on type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'

на линии return this.http.get(url, { headers: headers });

Кто-нибудь знает, как это исправить?

Ответы [ 3 ]

1 голос
/ 02 июля 2019

Это нормально, по умолчанию @RequestMapping("/user/logout") будет принимать только GET запросы. Вы должны установить метод явно

@RequestMapping("/user/logout", method = RequestMethod.POST)
public ResponseEntity<String> logout(){
    SecurityContextHolder.clearContext();
    return new ResponseEntity<String>("Logout Successfully!", HttpStatus.OK);
}

Или используйте @PostMapping

1 голос
/ 02 июля 2019

Попробуйте это:

constructor(private http:HttpClient){}
logout()
{
    const url = 'http://localhost:8181/user/logout';
    const headers = new HttpHeaders()
      .set('x-auth-token', localStorage.getItem('xAuthToken'));

    return this.http.post(url, '' ,{headers: headers, responseType: 'text'})};

Весной я рекомендую использовать аннотацию @PostMapping или @DeleteMapping вместо @RequestMapping. Причина использования ResponseType в качестве «текста» заключается в том, что вы предоставляете ResponseEntity<> типа String и по умолчанию Angular воспринимает ответ как JSON.

Кроме того, не забудьте использовать localStorage.removeItem('xAuthToken'); в ответе при подписке на это наблюдаемое, а также отписаться от того, что наблюдается в ngOnDestroy() жизненном цикле.

1 голос
/ 02 июля 2019

Попробуйте установить headers следующим образом:

let headers = new HttpHeaders();
headers = headers.set('x-auth-token', xToken).set('Authorization', basicHeader);

, а затем

return this.http.post(url, null, headers );

Pass null, поскольку он принимает body как во втором параметре.

Использование HttpClient :

import { HttpClient } from '@angular/common/http';

constructor(private http: HttpClient) { }

в app.module.ts:

import { HttpClientModule } from '@angular/common/http';

и в @NgModule: imports: [ HttpClientModule ]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...