【问题标题】:How to Logout in Angular / Spring by POST如何通过 POST 在 Angular / Spring 中注销
【发布时间】:2019-11-12 20:29:45
【问题描述】:

我想通过 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 });

有人知道怎么解决吗?

【问题讨论】:

  • 您可以发布您的component 代码吗?你在哪里打电话LoginService

标签: java angular spring spring-boot spring-mvc


【解决方案1】:

这很正常,默认情况下@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

【讨论】:

    【解决方案2】:

    试试这个:

    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'})};
    

    在 Spring 中,我的建议是使用 @PostMapping@DeleteMapping 注释而不是 @RequestMapping。使用ResponseType 作为“文本”的原因是因为您提供ResponseEntity&lt;&gt; String 类型,默认情况下Angular 将响应视为JSON。

    此外,请记住在订阅该可观察对象时在响应中使用localStorage.removeItem('xAuthToken');,并在ngOnDestroy() 生命周期中取消订阅该可观察对象。

    【讨论】:

    • 那么HttpHttpClient有什么区别呢?我在构造函数中使用了private http: Http,但现在我需要定义另一个private http:HttpClient 来使用POST 方法?为什么我不能从httpHttpClient 获得POST 和GET 方法
    • http 模块是一个已弃用的模块,HttpClient 模块是Httpmodule 的改进替代品。对于所有类型的请求,无论是 GET、POST、PUT、PATCH 还是 DELETE,都必须使用 httpClient。 HttpClient 模块是在 4.3 中引入的,它有很多好处,例如进度事件、中间件逻辑的拦截器。结论是使用 HttpClient 而不是 Http,因为它已被 Angular 团队弃用
    • 我修改为使用HttpClient ,但遇到了其他问题。我已经在我的帖子上更新了我的代码。如果可能,请查看并帮助我。
    • Headers 是 http 模块的一部分,它也被弃用了。所以,现在你需要以这种方式设置标题:new HttpHeaders().set('name', value)' 例如,在 sendCredential() 中你必须使用const headers = new HttpHeaders().set( 'Content-Type','application/x-www-form-urlencoded').set('Authorization', basicHeader); return this.http.get(url, { headers: headers });
    • 很好,但我收到了这个错误localStorage.setItem('xAuthToken', res.json().token); 因为Property 'json' does not exist on type 'Object'.?我改成res.toString()了,还是不行。
    【解决方案3】:

    尝试像这样设置headers

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

    然后,

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

    传递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 ]

    【讨论】:

    • 我试过了,但得到了错误Type 'HttpHeaders' is missing the following properties from type 'Headers': forEach, values, toJSON, entries, mayBeSetNormalizedNamets(2739)。如果我更改为return this.http.post(url, headers, null );,我会得到同样的错误
    • 你能确认你使用的是HttpClientModule
    • this.http --> 请显示你的构造函数(http:HttpClientModule )
    • @mrSmith91 帖子存在于 HttpClientModule 中,可能存在一些语法问题
    • 我没有骗你。我为您粘贴错误消息:Property 'post' does not exist on type 'HttpClientModule'.ts(2339)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 2016-04-18
    • 2017-11-05
    • 2021-11-08
    • 1970-01-01
    • 2021-04-17
    相关资源
    最近更新 更多