ajax 如何保證數據的安全性


假如跨站偽造請求成功,怎么保證 ajax 的數據安全性?

問題的根源

答主 bumfod 說的確實有道理。crsf 的成因在一定程度上確實是由於http有狀態的原因(cookie維持狀態),並不是我之前所說的是 http無狀態的原因
在此如果有人被誤導,我表示抱歉。

我們如果能驗證請求確實來是用戶確認(自願)發出的,而不是用戶誤導的情況下發出的,就能解決這個問題。

檢查Referer標頭確實是一種方案,但是該標頭也有可能被篡改,而且瀏覽器的實現不一。

舉個例子

以RESTful服務為例。

我們假設有一個資源Books

我們現在要對 Books 資源進行 POST 動作(請求)。那如何保證該動作不會被 csrf

通常的做法是

我們在請求 POST 之前,要獲取到改對POST請求的 token。只要在 POST 請求時攜帶對應的 token 才可以 200, 否則 就是 403。 (token 的生成算法多種多樣,主要看需求)

http請求實例

 // 獲取 token token = get_token(resource:'Books') // 請求 request(book).token(token).post() 

表單實例

傳統 form 表單提交,為了解決 csrf 都會提供如下解決方案。

 <form action="/books" method="POST" > <input type="text" name="name" /> <input type="text" name="author" /> <input type="text" name="publisher" /> <!-- csrf token --> <input type="hidden" name="token" value="j8i32hh2n2e8jdij92ecndaj9923dna9" /> </form> 

圖片描述

在打開表單頁面的時候,會給表單生成一個令牌(token),當表單提交的時候,就會根據令牌來驗證表單的合法性。

token 怎么來的

token 的算法多種多樣,有依賴於session的,有依賴於請求指紋的,有依賴於ip的,還有依賴於cookie的 等等。具體看業務需求。大多數 web 框架的實現都是使用httpOnly cookie,但是

RESTful服務框架都是依賴於請求指紋的。這些沒有什么好壞之分。

請求指紋: 一個請求有很多指紋信息,比如說請求的url和url中的信息,('/books'),請求的ip,請求的UA,請求的標頭信息,等等。請求指紋來計算token的話,可以保證無狀態特性。

依賴ip: 對請求的客戶端 ip 值進行 hash 來作為 token;這樣是沒有狀態的。

依賴session: 這種方法很適用於web網站,就是當用戶登錄后,對用戶的請求根據用戶的信息生成 token 存放到 session 中。

如何組織

例如:
我們要修改系統至用戶的信息。

/users 資源

在 post 之前我們需要先獲取 修改資源的 token。
請求 獲取 token

GET /access_token?uid=1001&scope=users&authorize=sujijd1026ajkshd28saos29hdandja HTTP/1.1 Authorization: sujijd1026ajkshd28saos29hdandja Accept: application/json;charset=utf8 Cache-Control: no-cache Host: localhost:8080 

后端可以根據標頭中的 Authorization, url 查詢字符串中的 uid, scope, authorize。來生成 access_token 比如使用 AES 堆成加密的base64字符串。最后能夠再加點鹽。
(這里標頭和查詢字符串中都存在 Authorization,可以自己取舍。)

返回 token

HTTP/1.1 200 OK Connection → keep-alive Content-Length → 2612 Content-Type → application/json; charset=utf-8 {"access_token": "diaj2iejqd8qqld9k92doijq9j2oie1u"} 

修改user的post請求

POST /users?access_token=diaj2iejqd8qqld9k92doijq9j2oie1u HTTP/1.1 Authorization: sujijd1026ajkshd28saos29hdandja X-Token: diaj2iejqd8qqld9k92doijq9j2oie1u Accept: application/json;charset=utf8 Cache-Control: no-cache Host: localhost:8080 {"name": "如何變得有思想", "author": "阮一峰", "publisher": "人民郵電出版社"} 

以上演示了如何組織一個使用令牌來實現csrf的請求。

回到問題上

回到問題的開始 ajax 該怎么做?

依然使用 /user/1001 為例,我們使用指紋加密的方法生成token。

/access_token 為令牌資源

 var $request = function(ajax_param1) { return function(data){ return $.ajax(merge(ajax_param1, {'data': data})); }; }; var get_token = $request({ 'type': 'GET', 'url': '/access_token' }); var create_book = function(book){ // post return get_token({uid: 1001}).then(function(token){ return $request({ 'type': 'POST', 'url': '/books', // 關鍵點 'headers': { 'x-crsf-token': token.access_token, 'Authorization': 'sujijd1026ajkshd28saos29hdandja' } })(book); }); } var book = {name: '如何變得有思想', author: '阮一峰', publisher: '人民郵電出版社'}; create_book(book).then(function(res){ console.log(res); // 200 ok! book created }); 

將token放到url上還是放到標頭中,具體看開發者的喜好了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM