钓鱼网站:搭建一个和正常网站一模一样的网页,只是后端提交数据的时候,不会按照你输入的用户桩长,而是将钱转到钓鱼网站自己默认设置好的账号中去,导致自己的转账不知去向
钓鱼网站的原理:搭建两个相同的前端页面,然后后端开设两个不同的端口,其中钓鱼网站的前端提交的地址设置为正确网站的地址
<h1>我是一个正儿八经的网站h1>
<form action="">
{% csrf_token %}
<p>username:<input type="text" name="username">p>
<p>target_name:<input type="text" name="target_name">p>
<p>money:<input type="text" name="money">p>
<input type="submit">
form>
body>
方法一:利用标签查找获取页面上随机字符串
方法二:利用模板语法提供的快捷方式
方法三:直接拷贝js代码,并应用到自己的html页面上
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
{% load static %}
<script src="{% static 'js/mysetup.js' %}"></script>
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
<script>
$('#d1').click( function () {
$.ajax({
url:'',
type:'post',
// 第一种方式:利用标签查找获取页面上随机字符串
{#data: {"username": 'jason', "csrfmiddlewaretoken": $('[name=csrfmiddlewaretoken]').val()},#}
// 第二种方式:利用模板语法提供的快捷方式
{#data: {"username": 'jason', "csrfmiddlewaretoken": {{csrf_token}},#}
// 第三种方式:直接拷贝js代码,并应用到自己的html页面上
success: function () {
}
})
})
</script>
1.当整个网站默认都不校验csrf 但是局部视图函数需要校验 如何处理
2.当整个网站默认都校验csrf 但是局部视图函数不需要校验 如何处理
from django.views.decorators.csrf import csrf_protect,csrf_exempt
@csrf_exempt
def home(request):
return render(request, 'home.html')
@csrf_protect
def login(request):
return render(request, 'login.html')
from django.utils.decorators import method_decorator
from django import views
# 方式二:指名道姓的添加
@method_decorator(csrf_protect, name='post')
class Myindex(views.View):
# 方式三: 直接影响类中的所有方法
def dispatch(self, request, *args, **kwargs):
super(Myindex, self).dispatch(request, *args, **kwargs)
# 方式1:直接指名道姓的添加
@method_decorator(csrf_protect)
def get(self, request):
return HttpResponse('get页面')
def post(self, request):
return HttpResponse('post页面')
from django.contrib.auth.models import User
User.object.create_user(username, password) # 创建普通用户,密码是没有被加密的
User.object.create_superuser(username, password,email) # 创建超级管理员用户
from django.contrib import auth
auth.authenticate(request,username,password)
auth.login(request, user_obj)
request.user.is_authenticated
request.user
from django.contrib.auth.decorators import login_required
# 局部配置
login_required(login_url='/login/')
# 全局配置
LOGIN_URL = '/login/'
request.user.check_password(old_password)
request.user.set_password(new_password)
request.user.save()
auth.logout(request)
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 登录
url(r'^login/', views.login),
# 登录之后的页面
url(r'^home/', views.home),
# 修改密码的页面
url(r'^set_password/', views.set_password),
# 注销账号
url(r'^logout/', views.logout),
# 注册用户
url(r'^register/', views.register),
]
from django.contrib import auth
from django.shortcuts import render, redirect, HttpResponse
# Create your views here.
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
# 用户表中的数据校验
# 表如何获取
# 密码如何比对
user_obj = auth.authenticate(request, username=username, password=password)
# 1.自动查找auth_user标签
# 2.自动给密码加密并比对
# 3.必须同时传用户名和密码
# 保存用户状态
if user_obj:
auth.login(request, user_obj)
# 只要执行了该方法,你就可以在任何地方通过request.user获取到当前登录的用户对象
return redirect('/home/')
return render(request, 'login.html')
from django.contrib.auth.decorators import login_required
# @login_required # # 全局配置
# @login_required(login_url='/login/') # 用户没登录的情况下,跳转到指定的页面 局部配置
def home(request):
"""用户登录之后才可以访问的页面"""
print(request.user)
print(request.user.is_authenticated()) # 判断当前用户是否登录
return HttpResponse('ok')
# 设置密码
@login_required
def set_password(request):
if request.method == 'POST':
old_password = request.POST.get('old_password')
new_password = request.POST.get('new_password')
confirm_password = request.POST.get('confirm_password')
if new_password == confirm_password:
if request.user.check_password(old_password):
request.user.set_password(new_password)
request.user.save()
return redirect('/login/')
return render(request, 'set_password.html', locals())
# 注销账号
@login_required
def logout(request):
auth.logout(request)
return redirect('/login/')
from django.contrib.auth.models import User
# 注册用户
@login_required
def register(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
# 创建普通用户
# User.objects.create_user(username=username, password=password)
User.objects.create_superuser(username=username, password=password, email='123@qq.com')
return render(request, 'register.html')
<form action="" method="post">
<h1>登录h1>
{% csrf_token %}
<p>username:<input type="text" name="username">p>
<p>password:<input type="text" name="password">p>
<p><input type="submit" value="登录">p>
form>
<form action="" method="post">
<h1>修改密码h1>
{% csrf_token %}
<p>username:<input type="text" name="username" disabled value="{{ request.user.username }}">p>
<p>old_password:<input type="text" name="old_password">p>
<p>new_password:<input type="text" name="new_password">p>
<p>confirm_password:<input type="text" name="confirm_password">p>
<input type="submit" value="确认">
form>
<form action="" method="post">
<h1>注册h1>
{% csrf_token %}
<p>username:<input type="text" name="username">p>
<p>password:<input type="text" name="password">p>
<p><input type="submit" value="注册">p>
form>
from django.contrib.auth.models import AbstractUser
class Userinfo(AbstractUser):
'''扩展auth_user表中没有的字段'''
phone = models.BigIntegerField()
desc = models.TextField()
AUTH_USER_MODEL = 'app01.Userinfo'
第一步:先创建一个notify文件夹,在该文件夹中可以创建py文件,eg:wechat.py, qq.py, email.py,__ init__.py
__ init__.py文件
import settings
import importlib
def send_all(content):
for path_str in settings.NOTIFY_LIST:
moudel_path, class_name = path_str.rsplit('.', maxsplit=1)
# 1.利用字符串导入模块
module = importlib.import_module(moudel_path)
# 2.利用反射获取类名
cls = getattr(module, class_name)
# 3.生成类对象
obj = cls()
# 4.利用鸭子类型直接调用send方法
obj.send(content)
email.py文件
class Email(object):
def __init__(self):
pass # 发送微信需要做的前期准备
def send(self, content):
print('邮箱通知:%s' % content)
qq.py文件
class QQ(object):
def __init__(self):
pass # 发送微信需要做的前期准备
def send(self, content):
print('QQ通知:%s' % content)
wechat.py文件
class Wechat(object):
def __init__(self):
pass # 发送微信需要做的前期准备
def send(self, content):
print('微信通知:%s' % content)
第二步:在项目根目录下还需要建两个py文件,分别是:start.py和settings.py
start.py文件
import notify
notify.send_all('下课了')
settings.py
NOTIFY_LIST = [
'notify.email.Email',
'notify.qq.QQ',
'notify.wechat.Wechat'
]