django表单验证和跨站伪造csrf

Form验证

django中的Form一般有两种功能:

  • 输入html
  • 验证用户输入

django使用内置form方法验证表单提交的数据

  • html页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .error-msg {
            color: red;
        }
    </style>
</head>
<body>
    <div>
        <div>
            用户名:<input type="text" name="user" />
        </div>
        <div>
            密码:<input type="password" name="pwd" />
        </div>
        <div>
           数字 <input type="text" name="num" />
        </div>
        <div>
            手机号<input type="text" name="phone" />
        </div>
        <div>
            邮箱<input type="text" name="email" />
        </div>
        <input type="button" value="提交" onclick="DoSubmit();" />
    </div>
    <script src="/static/js/jquery-1.12.4.js"></script>
    <script>
        function DoSubmit(){
            var input_dict = {};
            $(‘input‘).each(function(){
                var v = $(this).val();
                var n = $(this).attr(‘name‘);
                input_dict[n] = v;
            });
            $.ajax({
                url: ‘/login/‘,
                type: ‘POST‘,
                data: input_dict,
                dataType:‘json‘,
                success: function (result) {
                    if (result.status) {
                        location.href = ‘www.baidu.com‘;
                    } else {
                        $.each(result.message, function (k,v) {
                            var tag = document.createElement(‘span‘);
                            tag.className = ‘error-msg‘;
                            tag.innerText = v[0].message;
                            $(‘input[name="‘ + k + ‘"]‘).siblings(‘span‘).remove();
                            $(‘input[name="‘ + k + ‘"]‘).after(tag);
                        })
                    }
                }
            })
        }
    </script>
</body>
</html>
  • views函数
from  django import forms
import json
from django.core.exceptions import ValidationError
import re

#自定义验证规则
def mobile_validate(value):
    mobile_re = re.compile(r‘^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$‘)
    if not mobile_re.match(value):
        raise ValidationError(‘手机号码格式错误‘)

#定义验证规则
class MyForm(forms.Form):
    user = forms.CharField(required=True, error_messages={‘required‘: ‘用户名不能为空.‘})
    pwd = forms.CharField(required=True,
                          min_length=6, #最少长度
                          max_length=10,    #最大长度
                          error_messages={‘required‘: ‘密码不能为空.‘, ‘min_length‘: "至少6位"}, #不合法提示信息
                          widget=forms.PasswordInput)   #输入类型

    num = forms.IntegerField(error_messages={‘required‘: ‘数字不能空.‘, ‘invalid‘: ‘必须输入数字‘})
    email = forms.EmailField(required=True,error_messages={‘required‘: ‘邮箱不能空.‘, ‘invalid‘: ‘邮箱格式错误‘})
    #应用自定义验证规则
    phone = forms.CharField(required=True,validators=[mobile_validate,],error_messages={‘required‘:‘请填写手机号‘} )

def login(request):
    if request.method == ‘POST‘:
        result = {‘status‘:False,‘message‘:None}
        obj = MyForm(request.POST)
        ret = obj.is_valid()
        if ret:
            msg = obj.clean()
            result[‘status‘] = True
            result[‘message‘] = msg
        else:
            msg = obj.errors.as_json()  #将异常信息以json格式输出
            result[‘status‘] = False
            result[‘message‘] = json.loads(msg)
        print(result)
        return HttpResponse(json.dumps(result))
    else:
        return render(request,‘login.html‘)
  • url 配置略
  • 效果:
  • 涉及的知识点:
    • 1.html中form表单name的值需要和自己定义的类中的值必须一样,如input中name=user,那么,在class中对应的就是user=**的规则
    • 2.obj = MyForm(request.POST) 创建完对象之后,对象obj常用的方法有:
      • is_valid() 判断是否验证合法
      • clean() 取出request中验证通过的正确信息
      • errors 输出request中验证不通过的提示信息,子方法有 as_json() 以json格式输出、as_ul()以列表形式输出、 as_text()以字符串形式输出
    • 3.ajax拿到服务器返回的信息之后,判断message中status是否为True,为True则执行下一步操作,为false,则创建span标签,提示错误信息
    • 4.自定义验证规则:
      • 1)导入from django.core.exceptions import ValidationError
      • 2)定义验证函数,如果验证不通过,则使用raise主动抛出ValidationError错误信息
      • 3)在类中使用validators=[mobile_validate,]应用规则

django使用form生成表单,并做提交数据验证

上面的例子是在html中直接使用form表单,然后利用ajax提交数据到后台进行验证,下面的例子使用django生成form表单里的元素,然后进行提交验证

  • html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .error-msg {
            color: red;
        }
    </style>
</head>
<body>
    <form>
        <div>
            <div>
               用户名: {{ obj.user }}
                {% if obj.errors.user %}
                    <span class="error-msg"> {{ obj.errors.user.0 }}</span>
                {% endif %}
            </div>
            <div>
                密码:{{ obj.pwd }}
                {% if obj.errors.pwd %}
                    <span class="error-msg"> {{ obj.errors.pwd.0 }}</span>
                {% endif %}
            </div>
            <div>
                数字:{{ obj.num }}
                {% if obj.errors.num %}
                    <span class="error-msg"> {{ obj.errors.num.0 }}</span>
                {% endif %}
            </div>
            <div>
               手机号: {{ obj.phone }}
                {% if obj.errors.phone %}
                <span class="error-msg"> {{ obj.errors.phone.0 }}</span>
                {% endif %}
            </div>
            <div>
               邮箱: {{ obj.email }}
                {% if obj.errors.email %}
                <span class="error-msg"> {{ obj.errors.email.0 }}</span>
                {% endif %}
            </div>
            <input type="submit" value="提交" />
        </div>
    </form>

</body>
</html>
  • view
def login2(request):
    if request.POST:
        objPost = MyForm(request.POST)
        ret = objPost.is_valid()
        if ret:
            print(objPost.clean())
        else:
            from django.forms.utils import ErrorDict
            #print(type(obj.errors),obj.errors.as_json())
            # obj1.errors
            pass
        return render(request, ‘login2.html‘,{‘obj‘: objPost})
    else:
        objGet = MyForm()
        return render(request, ‘login2.html‘,{‘obj‘: objGet})
  • url略
  • 涉及知识点
    • 1. 给django生成的标签应用样式和类型 widget 指定生成的标签类型 attr={‘k1‘:‘123‘} 指定属性 完整配置: pwd=forms.CharField(widget=forms.PasswordInput(attr={‘k1‘:‘123‘}))
    • 2.生成select标签

 

test_choices = (
(0, ‘上海‘),
(1, ‘背景‘),
)
test = forms.IntegerField(widget=forms.Select(choices=test_choices))


跨站伪造csrf

django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

  • 全局:

  中间件 django.middleware.csrf.CsrfViewMiddleware

  • 局部:

    • @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
    • @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
      注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

CSRF实现原理

  • 1.django在打开这个页面时就会给页面一个授权token,会分别在插入在cookie和给当前页面表单中插入一个input标签,所以浏览器必须开启cookie,或者表单中必须使用模版语言承接token
  • 2.对于普通表单,当点击submit之后,token会跟其他表单数据提交到后台,csrf拿到token之后,验证通过,否则返回403;对于ajax请求,则需要获取cookie中的token,然后特殊处理,进行提交
    ##实现过程
    ###普通表单
  • views配置
def csrf(request):
    return render(request,‘csrf.html‘)
  • html配置
<form action="csrf.html" method="post">
    <input type="text">
    <input type="submit" value="form提交">
    {% csrf_token%}     //承接csrf的token
</form>

打开html之后,发现,在html form表单中已经得道token

cookie中也得道了token

ajax使用token

  • html配置

需加入jquery.cookie插件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="csrf.html" method="post">
    <input type="text">
    <input type="submit" value="form提交">
    <!--{% csrf_token%}-->
</form>
<input type="button" value="Ajax提交" onclick="ajaxpost();">

<script src="/static/js/jquery-1.12.4.js"></script>
<script src="/static/js/jquery.cookie.js"></script>

<script>
    var csrftoken = $.cookie(‘csrftoken‘);
    function csrfSafeMethod(method) {
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    $.ajaxSetup({
        beforeSend: function (xhr,settings) {
            if (!csrfSafeMethod(settings.type) && (!this.crossDomain)) {
                xhr.setRequestHeader("X-CSRFToken",csrftoken);
            }
        }
    });
    function ajaxpost() {
        $.ajax({
            url:‘/csrf/‘,
            type:‘post‘,
            data:{‘k1‘:‘v1‘},
            success: function (data) {
                console.log(data)
            }

        });
    }
</script>

</body>
</html>
时间: 2024-08-24 20:03:26

django表单验证和跨站伪造csrf的相关文章

asp.net forms 表单验证 实现跨域共享cookie(即SSO,单点登录(在二级域名下))

1.前提: 需要做一个单点登录,使用asp.net自带的表单验证(FormsAuthentication) 配置文件怎么写,如下(基本的): <authentication mode="Forms"> <forms loginUrl="~/user/login" enableCrossAppRedirects="true" timeout="3600" name="qz.bbs" cook

17.Django表单验证

Django提供了3中方式来验证表单 官网文档:https://docs.djangoproject.com/en/1.9/ref/validators 1.表单字段验证器 a.引入:from django.core.exceptions import ValidationError b.定义验证方法,验证不通过抛一个ValidationError异常 def validate_name(value): 验证不通过 raise ValidationError("%s的信息已经存在"%v

Python菜鸟之路:Django 表单验证

前言 Django中完成表单验证,常用的有两种方法: 一种是通过HTML + JS + Ajax实现. 另一种是通过Django自身的forms模块来生成相应个HTML标签来完成表单验证.这是本节着重讲的地方 第一种方法:html + ajax实现基本的login页面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>

python_way day14 HTML-day5 (form表单验证,)

python-way day19 1. dJango的form表单验证 一,django表单验证功能 1.django验证基础: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>django form</title> </head> <body> <div> <i

实现跨浏览器html5表单验证

div:nth-of-type(odd){ float: left; clear: left; } .origin-effect > div:nth-of-type(even){ float: right; clear: right; } .clearfix:after{ content: ""; display:block; clear: both; } .figcaption{ clear: both; color: #999; padding-top: 10px; text

django之form表单验证

django中的Form一般有两种功能: 输入html 验证用户输入 #!/usr/bin/env python # -*- coding:utf-8 -*- import re from django import forms from django.core.exceptions import ValidationError def mobile_validate(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]

Python自动化运维系列之Django Form表单验证

Form表单验证 Django核心功能组件之一,虽然也可以在前端使用JS对表单验证, 但是Django中已经为我们准备好的Form功能还算是很强大的,有时候比较适合运维,为我们简化了很多前端开发工作. Django最主要的几个功能有4个     ·  生成HTML标签     ·  验证数据(表单错误信息提示)     ·  HTML 表单保留上次提交数据     ·  初始化页面表单内容 Django的Form内容还是挺多的,我们可以从一个简单的登陆验证例子来看看Form的基本功能使用 1)新

Django基础之Form表单验证

Form表单验证 1.创建Form类(本质就是正则表达式的集合) from django.forms import Form from django.forms import fields from django.forms import widgets from Mybbs.models import * import re class UserForm(Form): username = fields.CharField( required=True, error_messages={'re

Django之表单验证

对于前端的表单进行验证的方法,从最简单的js到基于XML传输的Ajax,再到cookie的免认证,现在Django为我们提供了自带的表单验证方法. views.py: from django import forms class FM(forms.Form): #这里要接受后端需要的,不需要的数据不会关注 required='不能为空' username=forms.CharField(error_messages={'required':required}) #表单中的name要与变量名一样