星期二, 8月 09, 2016

Kendo Grid 教學 4 - 解決 REST Service 回應 HTTP 403

在先前「RestTemplate 無法呼叫 Rest Service」的文章中有提到,有些後台被 Spring Security 保護著,並啟用 Cross-site request forgery (CSRF) 的保護機制,並免他人因為知道服務的端點,就可以直接呼叫相關的服務。

Kendo UI 可以透過 Datasource 中 transport 的屬性設定,可以完成資料的讀取及寫入工作。針對新增、修改、刪除及查詢的部分,分別提供 create、update、destory 及 read 的 function 來進行相關作業的處理。
    transport:{
        create:{...},
        update:{...},
        destroy{...},
        read{...}
    }
開發人員可透過上述設定,完成 kendo grid 上 CRUD 的相關動作。

但是,當我們碰上後端具有 CSRF 保護的服務時,可能會出現 「HTTP 403 : Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'」的錯誤訊息。

這代表,我們正常地呼叫後端的服務。以整合 Spring Security 來說,當我們完成登入後,可以從 Request Header 中觀察到,HTTP Request 都會帶著兩個 Cookies 的資訊,分別是 JSESSIONID 及 XSRF-TOKEN 資訊。

然後,我們再看一下錯誤的訊息「HTTP 403 : Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'」。看起來,後端要的服務需要我們的 Header 送一個 X-CSRF-TOKEN 的資訊過去。上網找一下參考資料「Invalid CSRF Token 'null' 解決方案」看起來也是這樣說明沒錯。而且,X-CSRF-TOKEN 的內容跟 XSRF-TOKEN 一樣 (一樣的東西,底層竟然沒有自己處理掉 .... 看來還要找時間看看到底為什麼有這樣的限制)。 

所以,接著要思考的是如何在 Kendo Grid 呼叫後端服務時,將  X-CSRF-TOKEN 動態的塞入。後來,我在 「Transport and basic authentication」找到了解答。我們可以在 create、update、destroy 跟 read 等方法上加上 「beforeSend」的方法來加入 X-CSRF-TOKEN。

beforeSend: function(req){
    req.setRequestHeader('X-XSRF-TOKEN', $cookies.get('XSRF-TOKEN'));
}
如此一來,就可以正常使用後端服務了!

[參考資料]
1. 跨網站請求偽造
2. Invalid CSRF Token 'null' 解決方案
3. Transport and basic authentication

沒有留言: