1. 前后端分离中csrf token的作用
在Django的前后端分离应用中,csrf token的作用是保护应用不受到跨站请求伪造攻击(Cross-Site Request Forgery,CSRF)的影响。这种攻击方式是因为Web应用未能对用户的请求进行充分验证而发生的。攻击者可以在用户已登录状态下,通过某个URL链接或图片等方式,向Web应用发送请求,在未得到用户授权的情况下执行危险操作。
如果应用没有启用csrf保护,攻击者可以伪造POST请求,将用户的资料以某种方式修改或删除。启用csrf保护可以减少这种攻击的可能性。
2. 前后端分离中csrf token的获取
2.1 在Django中获取csrf token
在Django中,django.middleware.csrf.CsrfViewMiddleware中间件会将csrf token添加到每个响应中,前端可以通过从响应中提取token来进行验证。
from django.views.decorators.csrf import get_token
def my_view(request):
token = get_token(request)
# ...
这里get_token是从CsrfViewMiddleware中获取csrf token的函数。
2.2 通过Javascript获取csrf token
在前端JavaScript中,可以通过从cookie或HTTP响应头部中提取csrf token来进行验证。
首先,在cookie中查找csrf token:
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// 此处默认cookie的名称为csrftoken,如果自己设定了名称需要替换
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
然后,如果在cookie中未找到csrf token,可以从HTTP响应头中提取:
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
let csrftoken = getCookie('csrftoken');
if (!csrftoken) {
const csrfElement = document.getElementsByName('csrfmiddlewaretoken')[0];
if (csrfElement) {
csrftoken = csrfElement.value;
}
}
这里首先尝试从cookie中查找csrf token,如果cookie中未找到,在csrfmiddlewaretoken的name属性查找csrf token的input元素。
3. 在前后端分离应用中使用csrf token
在前后端分离应用中,可以将csrf token添加到每个请求中,用于验证。
在JavaScript中,可以通过XMLHttpRequest对象或Fetch API添加csrf token到请求中:
const request = new XMLHttpRequest();
request.open('POST', '/some/request/url');
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 将csrf token添加到请求头中
request.setRequestHeader('X-CSRFToken', csrftoken);
const requestData = new FormData();
requestData.append('name', 'value');
request.send(requestData);
也可以使用Fetch API:
fetch('/some/request/url', {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
// 将csrf token添加到请求头中
'X-CSRFToken': csrftoken
},
method: 'POST',
body: 'name=value'
});
在axios中添加csrf token:
import axios from 'axios';
// 将csrf token添加到axios的全局请求头中
axios.defaults.headers.common['X-CSRFToken'] = csrftoken;
axios.post('/some/request/url', { data: 'value' });
这里使用axios.post()进行POST请求,并将数据传递给服务器。
4. 总结
在Django的前后端分离中,csrf token是用于保护应用免受跨站请求伪造攻击的关键要素。在JavaScript中,可以通过从cookie或HTTP响应头部中提取csrf token来进行验证,然后将csrf token添加到每个请求中。
使用csrf保护可以减少应用受到攻击的可能性,同时不影响正常的用户体验。