2014-06-09 200 views
24

我建立一個AngularJS有一個RESTful API(1.2.16)的Web應用程序,我要寄401級未授權的響應,其中認證信息是無效的或不存在請求不HTTP基本驗證對話框。當我這樣做時,即使使用HTTP攔截器,當通過AngularJS發出AJAX請求時,我也會看到瀏覽器提供的基本「需要身份驗證」對話框。我的攔截器在之後運行那個對話框,這對於做一些有用的事來說已經太晚了。使用AngularJS攔截

一個具體的例子:

我的後端API返回401 /api/things除非授權令牌存在。很好很簡單。

在AngularJS應用程序方面,我已經在config塊看了看docs,並設置了一個攔截器是這樣的:

$httpProvider.interceptors.push(['$q', function ($q) { 
    return { 
    'responseError': function (rejection) { 
     if (rejection.status === 401) { 
     console.log('Got a 401') 
     } 
     return $q.reject(rejection) 
    } 
    } 
}]) 

當我打開我的應用程序,除去身份驗證令牌,並執行AJAX調用/api/things(有希望觸發上述攔截器),我看到:

Authentication Required

如果我取消該對話框中,我看到的console.log輸出「有一個401」,我希望看到的而不是對話

Got a 401

顯然,攔截器工作正常,但它攔截爲時已晚!

我看到網絡上關於在短短這樣的情況下AngularJS認證無數的帖子,他們似乎都使用HTTP攔截器,但它們都沒有提到基本身份驗證對話框彈出。我對其外觀的一些錯誤想法包括:

  • 缺失Content-Type: application/json響應標題?不,它在那裏。
  • 需要返回承諾拒絕以外的內容嗎?無論返回什麼,該代碼總是在對話框後運行。

我失去了一些設置步驟或使用攔截錯誤?

+0

爲什麼你沒有使用403而不是401? –

+0

我使用了401,因爲在原始問題中,我刪除了身份驗證令牌(在我的情況下爲cookie)。 401是在此使用的正確響應代碼,因爲請求需要身份驗證,並且沒有提供任何身份驗證。 403用於提供身份驗證但服務器拒絕訪問資源。 –

回答

12

想通了!

訣竅是發送一個WWW-Authenticate響應標題的一些值,而不是Basic。然後,您可以用基本$http攔截,甚至更聰明像angular-http-auth東西捕捉401。

+6

請您詳細說明一下嗎? 「像angular-http-auth這樣更聰明的東西」要求服務器發送200響應。我在找服務器返回401代碼的解決方案。 – Romain

+0

我認爲它只在'授權'時彈出:'基本XXX' – killebytes

+0

請張貼一些代碼示例我有同樣的問題。 IOS基本身份驗證請求永不完成 –

1

以供將來參考

試圖處理401錯誤,當我想出了這個解決方案。 我沒有改寫Basicx-Basic或任何類似的選項,所以我決定來處理它與角客戶端。

啓動註銷時,首先嚐試用假用戶發出錯誤的請求,以丟棄當前緩存的憑證。

我有這個功能做的請求(它使用jQuery的$.ajax與殘疾人非同步調用):

function authenticateUser(username, hash) { 
    var result = false; 
    var encoded = btoa(username + ':' + hash); 

    $.ajax({ 
     type: "POST", 
     beforeSend: function (request) { 
      request.setRequestHeader("Authorization", 'Basic ' + encoded); 
     }, 
     url: "user/current", 
     statusCode: { 
      401: function() { 
       result = false; 
      }, 
      200: function (response) { 
       result = response; 
      } 
     }, 
     async: false 
    }); 

    return result; 
} 

所以,當我嘗試了登錄用戶,出現這種情況:

//This will send a request with a non-existant user. 
//The purpose is to overwrite the cached data with something else 
accountServices.authenticateUser('logout','logout'); 

//Since setting headers.common.Authorization = '' will still send some 
//kind of auth data, I've redefined the headers.common object to get 
//rid of the Authorization property 
$http.defaults.headers.common = {Accept: "application/json, text/plain, */*"}; 
8

我將此問題與Spring Boot Security(HTTP基礎版)一起使用,並且從Angular 1.3開始,您必須設置$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';以使彈出窗口不出現。

+1

它沒有爲我的應用程序與Angular 1.5和Firefox 48.x ...基本身份驗證提示符被解僱,即使與X-Requested-With頭... – ptitjuju69

+0

相同me.I我已經將此標題添加到郵遞員。但它不起作用。 –

+1

這解決了我的問題。瀏覽器身份驗證模式在應用您的問題後隱藏。謝謝。 – luffy