第一章 Django 基本使用
第二章 Django URL路由系统
第三章 Django 视图系统
第四章 Django 模板系统
第五章 Django 数据模型系统(基本使用)
第六章 Django 数据模型系统(多表操作)
第七章 Django 用户认证与会话技术
第八章 Django CSRF防护
CSRF,全称为Cross Site Request Forgery,中文名为跨站请求伪造
,是一种网络攻击方式。具体来说,攻击者通过诱骗用户点击链接或执行操作,从而在用户不知情的情况下以用户的身份发起恶意请求。
在Django框架中,CSRF保护默认只针对POST请求,也就是说Django默认对GET请求不做CSRF防御机制。这是因为GET请求通常不会导致数据的修改,所以被认为是安全的。而POST、PUT和DELETE等请求可能会对服务器端的数据产生影响,因此需要进行CSRF防护。
为了防止CSRF攻击,Django提供了CSRF中间件,该中间件默认在MIDDLEWARE配置中被激活。服务端响应时会分配一个随机字符串给客户端,客户端第二次发送post,put或delete请求时携带上次分配的随机字符串到服务端进行校验。如果禁用了CSRF中间件,并不推荐这样做,因为这样会增加被CSRF攻击的风险。开发者可以根据需要选择使用csrf_protect()方法对特定视图进行保护。
Django的CSRF保护工作原理基于以下几个步骤:
Django的CSRF防护机制主要通过以下几种方式实现:
# orm/setting.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', # 打开这一行
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# myorm/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
path('login/', views.login, name='login'),
path('home_page/', views.home_page, name='home_page'),
path('logout/', views.logout, name='logout'),
]
# myorm/views.py
from django.shortcuts import render, get_object_or_404,redirect,HttpResponse
from .models import Course, Student
from django.contrib import auth
from django.contrib.auth.decorators import login_required
# 定义一个装饰器
def self_login_required(func):
def inner(request):
is_login = request.session.get('is_login', False)
if not is_login:
return redirect(login)
else:
return func(request)
return inner
@self_login_required
def home_page(request):
return render(request,"home_page.html")
def login(request):
if request.method == "GET":
return render(request, "login.html")
elif request.method == "POST":
username = request.POST.get("username",None)
password = request.POST.get("password",None)
# 对用户数据验证
user = User.objects.filter(user=username)
if user:
for i in user:
passwd = i.password
if password == passwd:
# 验证通过后,将request与用户对象(包含session)传给login()函数
request.session['is_login'] =True
request.session['username'] = username
# 跳转到http://49.232.221.200:8080/myorm/home_page
return redirect("home_page")
else:
mag = '用户名密码错误'
else:
mag = '用户名密码错误'
return render(request, "login.html",{'mag': mag})
def logout(request):
# 清除当前用户的session信息
auth.logout(request)
return redirect('login')
<!-- myrom/templates/login.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="" method="post">
<h1>登录</h1>
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<button type="submit">登录</button>
</form><br>
<span style="color: red;">{{ mag }}</span>
</body>
</html>
<!-- myrom/templates/home_page.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>标题</title>
</head>
<body>
<h1>欢迎访问首页</h1>
<a href="/myorm/logout">退出</a>
</body>
</html>
http://49.232.221.200:8080/myorm/login/
输入账户名密码点击登录报错
{% csrf_token %}
增加这一行
<!-- myrom/templates/login.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<h1>登录</h1>
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<button type="submit">登录</button>
</form><br>
<span style="color: red;">{{ mag }}</span>
</body>
</html>
可以进行登录,检查源码
视图增加csrf_exempt也可以跳过防护
# myorm/views.py
from django.shortcuts import render, get_object_or_404,redirect,HttpResponse
from .models import Course, Student
from django.contrib import auth
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
# 定义一个装饰器
def self_login_required(func):
def inner(request):
is_login = request.session.get('is_login', False)
if not is_login:
return redirect(login)
else:
return func(request)
return inner
@self_login_required
def home_page(request):
return render(request,"home_page.html")
### 在这一进行添加然后跳过
@csrf_exempt
def login(request):
if request.method == "GET":
return render(request, "login.html")
elif request.method == "POST":
username = request.POST.get("username",None)
password = request.POST.get("password",None)
# 对用户数据验证
user = User.objects.filter(user=username)
if user:
for i in user:
passwd = i.password
if password == passwd:
# 验证通过后,将request与用户对象(包含session)传给login()函数
request.session['is_login'] =True
request.session['username'] = username
# 跳转到http://49.232.221.200:8080/myorm/home_page
return redirect("home_page")
else:
mag = '用户名密码错误'
else:
mag = '用户名密码错误'
return render(request, "login.html",{'mag': mag})
def logout(request):
# 清除当前用户的session信息
auth.logout(request)
return redirect('login')
这块不太清楚,也没有测试过,后续要是使用了,在进行更新
方法2:
var csrf_token = $("[name='csrfmiddlewaretoken']").val();
var data = {'id': '123', 'csrfmiddlewaretoken': csrf_token};
$.ajax({
type: "POST",
url: "/api",
data: data,
dataType: 'json'
})