1.views.py
# csrf验证:用于登录验证和登录之后的页面验证。
# 使用方法:只需要在html里面写上{% csrf_token %}即可,后面的验证都是django自动处理,不需要自己写处理验证方面的代码。
# 原理: # 用户点登录发出GET请求, # 服务器在(登录页面)html的form表单写上{% csrf_token %},并返回, # 浏览器自动生成被隐藏的input标签,里面的value值是随机字符串,输入用户名和密码之后,点登录,又把这个随机字符串以POST的形式发给服务器(django)做验证, # 并且给浏览器的cookie写上键值对,value值也是随机字符串, # 以后的每次请求(访问其他页面,触发后端的函数)都带着cookie, # 而django都会自动对cookie进行验证,验证有没这个随机字符串。
# 如果没有登录,就算cookie带着这个随机字符串来访问,就会报错。django对登录的随机字符串和cookie的随机字符串都进行了验证。 #之前自己写的cookie验证需要在每个函数上面添加验证的装饰器,而使用csrf就不需要了 # 不注释'django.middleware.csrf.CsrfViewMiddleware'
#为什么需要csrf验证?
#防止黑客在别的网站访问本站,盗取信息。只要用户在本站登录,才有随机字符串,才能访问本站的页面。但还是不能绝对安全,所以还需要额外的手机或者邮箱验证。 from django.shortcuts import render, HttpResponse def login(request): if request.method == 'GET': return render(request, 'login.html') else: return HttpResponse('ok') # 全局使用,局部禁用:遇到特殊的函数,不需要csrf验证的情况:使用csrf_exempt装饰器 # 不注释'django.middleware.csrf.CsrfViewMiddleware' from django.views.decorators.csrf import csrf_exempt @csrf_exempt def func1(): pass # 全局禁用,局部使用:使用csrf_protect装饰器 # 注释掉'django.middleware.csrf.CsrfViewMiddleware' from django.views.decorators.csrf import csrf_protect @csrf_protect def func2(): pass # 以上是fbv的csrf,下面是cbv的: # 类里面所有函数都使用: from django.views import View from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_protect @method_decorator(csrf_protect, name='dispatch') class Foo(View): def get(self, request): pass def post(self, request): pass # 额外:CBV中添加装饰器 def wrapper(func): def inner(*args, **kwargs): n = func(*args, **kwargs) return n return inner # 1. 在类上添加 from django.utils.decorators import method_decorator @method_decorator(wrapper, name='dispatch') class Foo(View): def get(self, request): pass def post(self, request): pass # 2.指定方法上添加装饰器 class Foo2(View): @method_decorator(wrapper) def get(self, request): pass def post(self, request): pass
2.login.html
<body>
<form method="POST" action="/login/">
{% csrf_token %}
<p>用户名:
<input type="text" name="name">
</p>
<p>密码:
<input type="password" name="password">
</p>
<p><input type="submit" value="登录"></p>
<p><input type="button" value="ajax登录"></p>
</form>
<script src="/static/jquery-3.4.1.min.js"></script>
<!--引用操作cookie的模块-->
<script src="/static/jquery.cookie.js"></script>
<script>
//1.随机字符串放在data中
/*
$("input[type='button']").on('click',function () {
//name='csrfmiddlewaretoken'可以从浏览器页面找到
var csrf = $("input[name='csrfmiddlewaretoken']").val();
var name = $("input[name='name']").val();
var password = $("input[name='password']").val();
$.ajax({
url:'/login/',
type:'POST',
//服务器通过request.POST.get('csrfmiddlewaretoken')拿到随机字符串
data:{'csrfmiddlewaretoken':csrf,'name':name,'password':password},
success:function (arg) {
alert('ok')
}
})
})
*/
//2.放在请求头中
$("input[type='button']").on('click', function () {
//通过jquery.cookie.js模块来获取随机字符串
var token = $.cookie('csrftoken');
var name = $("input[name='name']").val();
var password = $("input[name='password']").val();
$.ajax({
url: '/login/',
type: 'POST',
headers: {'X-CSRFToken': token},//放请求头中,固定写法
data: {'name': name, 'password': password},
success: function (arg) {
alert('ok')
}
})
})
</script>
</body>
3.页面和cookie的value
4.github也使用了csrf做登录验证: