CSRF

get请求,客户端获取csrf字符串,post请求把csrf字符串发送到服务端。

两种方式:
form表单:
render
{% csrf_token %}
ajax:
cookie中提取随机字符串
请求头headers
如果在headers中{'name':'yangxl'},在request的META中保存的是HTTP_NAME='yangxl',Django会自动把键变大写并添加HTTP_前缀。
怎么查看request/META,Django调试模式

查看Django中CSRF是怎么保存的:
class CsrfViewMiddleware(MiddlewareMixin):

def _accept(self, request):
pass

def _reject(self, request, reason):
pass

def process_view(self, request, callback, callback_args, callback_kwargs):
if getattr(request, 'csrf_processing_done', False):
return None

try:
cookie_token = request.COOKIES[settings.CSRF_COOKIE_NAME] #CSRF_COOKIE_NAME就是内存中crsftoken的名字。
......

def process_response(self, request, response):
pass

# 查看内存中的CSRF_COOKIE_NAME。
views.py
def login(request):
from django.conf import settings
print(settings.CSRF_HEADER_NAME) #HTTP_X_CSRFTOKEN,所以'x-csrftoken'就是。
print(request.method)
return render(request, 'login.html')

ajax方式:
login.html
<body>
<input id="btn" type="button" value="Ajax提交" />

<script src="/static/jquery-2.1.4.min.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
$(function () {
$('#btn').click(function () {
console.log('sdlf');
$.ajax({
url:"/login",
type:"POST",
data:{'name':'yangxl'},
headers:{'x-csrftoken': $.cookie('csrftoken')}, #headers请求头,'x-csrftoken'与Django中对应,$.cookie('csrftoken')从get方法返回的cookie中拿到'csrftoken'随机字符串。
success:function (arg) {
console.log(arg);
}
})
})
});
</script>
</body>

form方式:
login.html
<form action="/login" method="post">{% csrf_token %}
<input type="text" name="username">
<input type="submit" name="提交">
</form>

上面只针对了"/login"这一个url,怎么设置全局CSRF(ajax方式)?
<body>
<input id="btn" type="button" value="Ajax提交" />

<script src="/static/jquery-2.1.4.min.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
$(function () {
//全局设置。
$.ajaxSetup({
beforeSend: function(xhr, settings) { //beforeSend在发送ajax之前进行的操作
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken')); //xhr是xmlhttpresrequest对象
}
});

$('#btn').click(function () {
console.log('sdlf');
$.ajax({
url:"/login",
type:"POST",
data:{'name':'yangxl'},
//headers:{'x-csrftoken': $.cookie('csrftoken')}, //去掉局部设置。
success:function (arg) {
console.log(arg);
}
})
})
});
</script>
</body>

局部设置csrf:
from django.views.decorators.csrf import csrf_exempt,csrf_protect

@csrf_protect #全局不要csrf验证,只有这个函数需要。
@csrf_exempt #全局都要csrf验证,只有这个函数不要。
def login(request):
from django.conf import settings
print(settings.CSRF_HEADER_NAME)
print(request.method)
return render(request, 'login.html')

posted @ 2017-05-07 18:32  羊小羚  阅读(113)  评论(0)    收藏  举报