【Web前端问题】ajax 如何保证数据的安全性?
假如跨站伪造请求成功,怎么保证 ajax 的数据安全性?
回答:
从本质来讲ajax请求就是http请求。
问题的根源
答主 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
都会提供如下解决方案。
html
<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
http
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 OKConnection → keep-alive
Content-Length → 2612
Content-Type → application/json; charset=utf-8
{"access_token": "diaj2iejqd8qqld9k92doijq9j2oie1u"}
修改user的post请求
POST /users?access_token=diaj2iejqd8qqld9k92doijq9j2oie1u HTTP/1.1Authorization: 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
为令牌资源
javascript
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上还是放到标头中,具体看开发者的喜好了。
回答:
身份校驗是一切安全/加密傳輸的前提。
保障傳輸數據安全,首先要防止身份僞造。
防止身份僞造,只要設置一段只有身份正確時纔可能有的信息即可。
這種東西叫做密碼(password,用於身份校驗的保密字符串,不一定非得是用戶名/密碼組合中的密碼,也可以是 token)。
題主關注的是跨站請求僞造,那麼只要把密碼儲存在 CSRF 所無法得到的地方即可。
CSRF 只能僞造用戶進行操作,無法僞造用戶獲取信息。
然而 cookies 會被瀏覽器自動一起發送,達不到識別的目的,
所以一般的做法是在表單中添加一項 token:
由於 CSRF 的本質在於攻擊者欺騙用戶去訪問自己設置的地址,所以如果要求在訪問敏感數據請求時,要求用戶瀏覽器提供不保存在 cookie 中,並且攻擊者無法偽造的數據作為校驗,那麼攻擊者就無法再執行 CSRF 攻擊。這種數據通常是表單中的一個數據項。服務器將其生成並附加在表單中,其內容是一個偽亂數。當客戶端通過表單提交請求時,這個偽亂數也一並提交上去以供校驗。正常的訪問時,客戶端瀏覽器能夠正確得到並傳回這個偽亂數,而通過 CSRF 傳來的欺騙性攻擊中,攻擊者無從事先得知這個偽亂數的值,服務器端就會因為校驗 token 的值為空或者錯誤,拒絕這個可疑請求。
http://zh.wikipedia.org/wiki/跨站请求伪造
樓下認爲 CSRF 的本質是 HTTP 請求無狀態,
這是錯誤的(現已修正,點讚!)。
CSRF 恰恰就是利用了瀏覽器存在漏洞的對「有狀態」HTTP 的實現,也就是 cookie。
所以,即便 HTTP 請求有狀態,只要瀏覽器不校驗調用者身份,依舊會被 CSRF。
CSRF 是欺騙用戶瀏覽器,讓其以用戶的名義執行操作。
(同樣出自維基百科)
回答:
项目是前后端分离的话,如何保证安全性。
回答:
一般使用cookie加密,在后端验证cookie是否通过
以上是 【Web前端问题】ajax 如何保证数据的安全性? 的全部内容, 来源链接: utcz.com/a/142399.html