Angular 对 POST/PUT 请求放弃授权 header

Angular dropping Authorization header on POST/PUT requests

我有一个 Angular 应用程序可以与托管在 heroku 上的 API 通信。简单地说,它是一个电影数据库,您可以在收藏夹中添加和删除电影。

添加电影的请求:

  addMovie(username: any, movieId: any): Observable<any> {
    const token = localStorage.getItem('token');
    return this.http.post(apiUrl + `users/${username}/movies/${movieId}`, {headers: new HttpHeaders(
      {
        Authorization: 'Bearer ' + token,
      }
    )}).pipe(
      map(this.extractResponseData),
      catchError(this.handleError)
    );
  }

并删除电影:

  deleteMovie(username: any, movieId: any): Observable<any> {
    const token = localStorage.getItem('token');
    return this.http.delete(apiUrl + `users/${username}/movies/${movieId}`, {headers: new HttpHeaders(
      {
        Authorization: 'Bearer ' + token,
      }
    )}).pipe(
      map(this.extractResponseData),
      catchError(this.handleError)
    );
  }

两个请求完全相同,但 POST 请求出于某种原因放弃了授权 header 而 DELETE 请求则没有。查看两者的预检请求时,POST 请求的预检甚至不请求允许授权 header,而 DELETE 请求的预检允许。

POST 的预检:

curl "https://somesite.com/users/tester/movies/6123fbc6a2a0fea2b1f81fd1" ^
  -X "OPTIONS" ^
  -H "Connection: keep-alive" ^
  -H "Accept: */*" ^
  -H "Access-Control-Request-Method: POST" ^
  -H "Access-Control-Request-Headers: content-type" ^
  -H "Origin: http://localhost:4200" ^
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36" ^
  -H "Sec-Fetch-Mode: cors" ^
  -H "Sec-Fetch-Site: cross-site" ^
  -H "Sec-Fetch-Dest: empty" ^
  -H "Referer: http://localhost:4200/" ^
  -H "Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7" ^

DELETE 的预检:

curl "https://somesite.com/users/tester/movies/61240c5da2a0fea2b1f81fd9" ^
  -X "OPTIONS" ^
  -H "Connection: keep-alive" ^
  -H "Accept: */*" ^
  -H "Access-Control-Request-Method: DELETE" ^
  -H "Access-Control-Request-Headers: authorization" ^
  -H "Origin: http://localhost:4200" ^
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36" ^
  -H "Sec-Fetch-Mode: cors" ^
  -H "Sec-Fetch-Site: cross-site" ^
  -H "Sec-Fetch-Dest: empty" ^
  -H "Referer: http://localhost:4200/" ^
  -H "Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7" ^

用 PUT 替换 POST 会导致同样的问题。

POST request is the body. The third argument in a POST request is options. The second argument in a DELETE request 中的第二个参数是选项。当前,您在 POST 请求的 body 中发送身份验证 header,但它属于选项。

你可以发送一个空的body

addMovie(username: any, movieId: any): Observable<any> {
  const token = localStorage.getItem('token');
  return this.http.post(apiUrl + `users/${username}/movies/${movieId}`, {}, {headers: new HttpHeaders(
    {
      Authorization: 'Bearer ' + token,
    }
  )}).pipe(
    map(this.extractResponseData),
    catchError(this.handleError)
  );
}