Angular HttpClient帖子无效

时间:2017-11-17 23:21:56

标签: angular rest http oauth-2.0

我正在更改我的代码,将我的http api从'@ angular / http'更改为'@ angular / common / http'。我的大多数请求都工作正常,但是无论我怎么努力,带来刷新令牌的身份验证都无法正常工作....请看,我的代码如下:

    const headerHttp = new HttpHeaders();
    headerHttp.set('Content-Type', 'application/x-www-form-urlencoded');
    headerHttp.set('Authorization', 'Basic YW5ndWxhcjphbmd1bGFy');

    this.clientHttp.post(this.oauthTokenUrl,
      { username: user, password: pwd , grant_type: 'password' },
      {  headers: headerHttp, withCredentials: true })
        .subscribe(
      res => {
         console.log(res);
      },
      err => {
         console.log('Error occured');
      }
    );

但是参数(用户名,密码和grant_type)没有到达服务器并且输入屏幕正在弹出。

enter image description here

这是我的请求的结果,使用'@ angular / http':

图片1 enter image description here

这是我的请求无效的结果,我在上面提到了哪些代码。

图像2 enter image description here

编辑 1 - 验证输入屏幕不再弹出,代码如下。

const _params = new HttpParams()
.set('grant_type', 'password')
.set('username', usuario)
.set('password', senha );

const _headers = new HttpHeaders()
  .set('Authorization', 'Basic YW5ndWxhcjphbmd1bGFy')
  .set('Content-Type', 'application/x-www-form-urlencoded');

const httpOptions = {
  headers: _headers,
  params: _params,
  withCredentials: true
};

this.clientHttp.post<String>(this.oauthTokenUrl, httpOptions).subscribe(
res => {
  console.log(res);
},
err => {
  console.log('Error occurred', err);
});

这个是我以前的代码,并且工作正常。

    const headers = new Headers();

    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    headers.append('Authorization', 'Basic YW5ndWxhcjphbmd1bGFy');

    const body = `username=${usuario}&password=${senha}&grant_type=password`;

    return this.http.post(this.oauthTokenUrl, body,
        { headers, withCredentials: true })
      .toPromise()
      .then(response => {
        this.armazenarToken(response.json().access_token);
      })
      .catch(response => {
        if (response.status === 400) {
          const responseJson = response.json();

          if (responseJson.error === 'invalid_grant') {
            return Promise.reject('Usuário ou senha inválida!');
          }
        }

        return Promise.reject(response);
      });
  }

但是现在HttpClient创建了“请求有效负载”而不是“表单数据”。为什么? servlet无法像读取“表单数据”那样读取“请求有效负载”,因此它无法正确进行身份验证。

编辑2 - 解决方案

经过大量的尝试,使它工作的是一个新的FormData(),我按照@mtpultz建议。

const params = new HttpParams()
.set('grant_type', 'password')
.set('username', user)
.set('password', pwd );

const headers = new HttpHeaders()
  .set('Authorization', 'Basic xpto')
  .set('Content-Type', 'application/x-www-form-urlencoded');

const httpOptions = {
  headers: headers,
  params: params,
  withCredentials: true
};

//The line works ( Requisition with Form Data, like IMAGE 1 above )
this.httpClient.post<Response>(this.oauthTokenUrl,  new FormData(), httpOptions )

//The line, without new FormData(), doesn't work.  ( Requisition with Request Payload, like IMAGE 2 above )
this.httpClient.post<Response>(this.oauthTokenUrl,  httpOptions )

1 个答案:

答案 0 :(得分:2)

将您的代码放入stackblitz example这似乎在您在控制台中查看时发送Form Data而不是Request Payload。它正确发送的原因我认为是基于本机表单提交表单字段名称/值对作为查询字符串,将它们添加为params mimics。

  public test() {
    const headers = new HttpHeaders({
      'Content-Type': 'application/x-www-form-urlencoded',
      'Authorization': 'Basic YW5ndWxhcjphbmd1bGFy'
    });
    const params = new HttpParams()
      .set('username', 'test@example.com')
      .set('password', 'secret')
      .set('grant_type', 'password');
    const options = {
      headers,
      params,
      withCredentials: true
    };
    this.httpClient.post('https://reqres.in/api/example', null, options)
      .subscribe(response => console.log(response));
  }

此外,我建议您使用Observables而不是将您的回复转换为Promises。如果您对Observables感到不舒服,但为了处理HTTP请求,我们需要花很长时间才能学习一些基础知识。