2017-11-17 168 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