csrf跨站请求伪造,csrf相关的装饰器,auth认证模块,auth_user表切换,基于django中间件设计项目功能

一:csrf跨站请求伪造

1.前戏

钓鱼网站:搭建一个和正常网站一模一样的网页,只是后端提交数据的时候,不会按照你输入的用户桩长,而是将钱转到钓鱼网站自己默认设置好的账号中去,导致自己的转账不知去向

钓鱼网站的原理:搭建两个相同的前端页面,然后后端开设两个不同的端口,其中钓鱼网站的前端提交的地址设置为正确网站的地址

2.什么是csrf跨站请求伪造?
  • 网站在给用户返回一个具有提交数据功能的页面的时候,会给这个页面加上一个唯一标识,当这个页面朝后端发送post请求的时候,
  • 后端会自动校验这一标识,如果标识不对,则直接拒绝(403frobbiden),如果标识正确,则正常执行执行
3.form表单中的csrf操作:
  • 方法一:直接在前端页面的form表单中添加{% csrf_token %}
<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>
4.ajax中的csrf操作
  • 方法一:利用标签查找获取页面上随机字符串

  • 方法二:利用模板语法提供的快捷方式

  • 方法三:直接拷贝js代码,并应用到自己的html页面上

    • 1.创建静态文件夹static
    • 2.在文件夹中创建js文件夹
    • 3.在js文件夹中创建mysetup.js文件,将配置的代码粘贴到里面
    • 4.在settings.py中添加静态文件配置
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'static')
    ]
    
    • 5.在项目文件中导入该js文件即可
    {% 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>

二:csrf相关装饰器

1.前提

1.当整个网站默认都不校验csrf 但是局部视图函数需要校验 如何处理
2.当整个网站默认都校验csrf 但是局部视图函数不需要校验 如何处理

2.FBV中的装饰器
  • 装饰器1:csrf_protect 校验csrf
  • 装饰器2:csrf_exempt 不校验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')
3.CBV中的装饰器
  • 1.csrf_protect
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页面')

  • 2.csrf_exempt:只有方式3有效 针对其他装饰器上述三种方式都有效

三:auth认证模块

1.auth模块中的常见方法
1.创建用户:
  • 创建普通用户:密码是不被加密的
  • 创建超级管理员:必须添加一个email参数
from django.contrib.auth.models import User
User.object.create_user(username, password)  # 创建普通用户,密码是没有被加密的
User.object.create_superuser(username, password,email)  # 创建超级管理员用户
2.校验用户名和密码
  • authenticate方法
from django.contrib import auth
auth.authenticate(request,username,password)
3.用户登录
auth.login(request, user_obj)
4.判断用户是否登录
request.user.is_authenticated
5.获取登录用户对象
request.user
6.校验用户登录装饰器
  • 局部配置
  • 全局配置:配置到settings.py文件中
from django.contrib.auth.decorators import login_required
# 局部配置
login_required(login_url='/login/')

# 全局配置
LOGIN_URL = '/login/'
7.校验密码是否正确
request.user.check_password(old_password)
8.修改密码
  • 切记:修改密码之后一定要保存
request.user.set_password(new_password)
request.user.save()
9.注销登录
auth.logout(request)
10.练习
  • urls.py
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),
]
  • views.py
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>

四:auth_user表切换

  • 第一步:models.py中
from django.contrib.auth.models import AbstractUser

    class Userinfo(AbstractUser):
        '''扩展auth_user表中没有的字段'''
        phone = models.BigIntegerField()
        desc = models.TextField()
  • 第二步:settings.py中
AUTH_USER_MODEL = 'app01.Userinfo'
总结:
  • 1.如果继承了AbstractUser,那么在执行数据库迁移命令的时候,auth_user表就不会再被创建出来
  • 2.UserInfo表会创建,并且它里面包含auth_user表中所有的字段,并且还可以增加自己独有的字段
  • 3.在执行数据库迁移命令之前,不能存在已经创建好的auth_user表,如果存在,则直接换库
  • 4.新表中只能创建auth_user表中没有的字段
  • 5.必须在配置文件中声明:AUTH_USER_MODEL = ‘app01.UserInfo’

五:基于django中间件设计项目功能

第一步:先创建一个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'
]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 Django 自带的用户认证系统实现注册功能,可以按照以下步骤操作: 1. 在 `settings.py` 文件中设置 `AUTH_USER_MODEL` 为自定义的用户模型(如果没有自定义用户模型,可以跳过此步骤): ```python AUTH_USER_MODEL = 'myapp.CustomUser' ``` 2. 在 `urls.py` 文件中导入 `django.contrib.auth.views` 模块: ```python from django.contrib.auth import views as auth_views ``` 3. 添加注册页面的 URL 路由,指定视图函数为 `auth_views.RegisterView.as_view()`: ```python urlpatterns = [ # ... path('register/', auth_views.RegisterView.as_view(), name='register'), ] ``` 4. 在注册页面模板中,使用 Django 自带的单 `UserCreationForm` 实现注册单: ```html {% extends 'base.html' %} {% block content %} <h2>Register</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Register</button> </form> {% endblock %} ``` 注意,`form.as_p` 会渲染单的 HTML 代码,包括单字段和标签。 5. 在视图函数中处理单数据,如果单验证通过,则创建新用户并自动登录: ```python from django.contrib.auth.forms import UserCreationForm from django.contrib.auth import authenticate, login from django.shortcuts import render, redirect def register(request): if request.method == 'POST': form = UserCreationForm(request.POST) if form.is_valid(): user = form.save() # 自动登录 username = form.cleaned_data.get('username') password = form.cleaned_data.get('password1') user = authenticate(request, username=username, password=password) login(request, user) return redirect('home') else: form = UserCreationForm() return render(request, 'registration/register.html', {'form': form}) ``` 注意,`form.cleaned_data` 包含经过验证的单数据,`authenticate` 函数用于验证用户身份,`login` 函数用于登录用户。 以上就是使用 Django 自带的用户认证系统实现注册功能的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值