2017-11-17 169 views
0

我正在更改我的代码,将我的http api从'@ angular/http'更改为'@ angular/common/http'。我的大部分请求都做工精细,但带给我的刷新令牌的认证不工作,无论我怎样努力....请,似乎我的代码波纹管:角度HttpClient发布不起作用

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

这是我的请求这样的作品,与我的结果 '@角/ HTTP':

IMAGE 1 enter image description here

这是我的要求,即没有按”的结果t工作,我上面提到的代码。

IMAGE 2 enter image description here

EDIT - 认证输入画面isn't与代码波纹管再弹出。

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创建一个“Request Payload”而不是“Form Data”。为什么?该servlet无法像读取“表单数据”一样读取“请求有效内容”,因此它不会正确执行认证。

EDIT 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) 
+0

您需要提供更多的周边代码,我认为这是为了解决这个问题,因为您所做的事似乎是正确的。 – mtpultz

+0

@mtpultz,我试图删除代码的所有环境,甚至是HttpInterceptor,而不改变结果。但是我增加了更多信息,这个问题似乎对我更加清楚。不幸的是,不是解决方案... :-(Tks! –

+1

Yah你原来的代码肯定无法工作,因为'HttpClient'请求和响应是不可变的,所以'headers.append(...)'实际上会返回一个副本,你将需要通过做'headers = headers.append(...)',但是你并没有存储它,如果你这样做,'headers'需要'let'而不是'const'。 – mtpultz

回答

2

把你的代码放到一个stackblitz example这似乎发送Form Data而不是Request Payload当您在控制台中查看。我相信它正确发送的原因是基于本地表单提交表单字段名称/值对作为查询字符串,它将它们添加为参数模仿。

public test() { 
    const headers = new HttpHeaders({ 
     'Content-Type': 'application/x-www-form-urlencoded', 
     'Authorization': 'Basic YW5ndWxhcjphbmd1bGFy' 
    }); 
    const params = new HttpParams() 
     .set('username', '[email protected]') 
     .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请求并不需要很长时间。

+0

它工作完美!谢谢你,@ mtpultz! –

+0

这个最后的版本,没有“新的FormData()”,没有工作。谢天谢地,您的第一个解决方案仍然存在:-)代码与上面相同,并加上“withCredentials:true”。我再次编辑添加“新FormData()”作为解决方案,即使它不完全清楚这种行为背后的原因。 –

+0

我不认为传递'新的FormData()使它正常工作。你应该能够通过'null'并得到相同的结果。我认为这是有效的,因为提交的本地表单会将表单字段名称/值对作为查询字符串添加到请求中。因此,通过将params添加为params生成模仿本机表单提交的相同查询字符串结果。 – mtpultz