目录
跨站请求伪造csrf
钓鱼网站
你自己写一个跟中国银行正规网站一模一样的页面
用户输入用户名 密码 对方账户 转账金额提交
请求确实是朝中国银行的接口发送的 钱也扣了
但是对方账户变了 变成了钓鱼网站自己提前设置好的账户
如何实现
你在写form表单的时候 让用户填写的对方账户input并没有name属性
而是你自己在内部偷偷隐藏了一个具有name属性的input框
并且value值是你自己的账户 然后将该标签隐藏了
模拟该现象的产生
创建两个django项目
如何解决该问题
只处理本网站发送的post请求
如何识别如何判断当前请求是否是本网张发出的
解决
网站在返回给用户一个form表单的时候 会自动在该表单隐藏一个input框
这个框的value是一个随机字符串 但是网站能够记住每一个浏览器发送的随机字符串
form表单解决
以后在写form表单的时候 你只需要在表单中写一个{% csrf_token %} <form action="" method="post"> {% csrf_token %} <p>username:<input type="text" name="username"></p> <p>target_account:<input type="text" name="target_user"></p> <p>money:<input type="text" name="money"></p> <input type="submit"> </form> <input type="hidden" name="csrfmiddlewaretoken" value="rJ47FeK9T55wavvVJGY6UxdM1kTMHhTqotGfaXjXIK8Ahz2Uvs02yR9T8bBn5q2D">
ajax如何解决
方式1 较为繁琐
先在页面任意的位置上书写{% csrf_token %}
然后在发送ajax请求的时候 通过标签查找获取随机字符串添加到data自定义对象即可
data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},
方式2 较为简单
data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
方式3 官网提供的文件 最通用的一种方式(全能)
直接兴建js文件拷贝代码 导入即可
你不需要做任何的csrf相关的代码书写
csrf相关的装饰器
from django.views.decorators.csrf import csrf_exempt,csrf_protect @csrf_exempt # 不校验 csrf def index(request): return HttpResponse('index') @csrf_protect # 校验 def login(request): return HttpResponse('login')
这两个装饰器在CBV上有何异同:
@method_decorator(csrf_exempt,name='post') # csrf_exempt不支持该方法 @method_decorator(csrf_exempt,name='dispatch') # csrf_exempt class MyIndex(views.View): @method_decorator(csrf_exempt) # 可以 def dispatch(self, request, *args, **kwargs): return super().dispatch(request,*args,**kwargs) def get(self,request): return render(request,'transfer.html') @method_decorator(csrf_exempt,name='post') # csrf_exempt不支持该方法 def post(self,request): return HttpResponse('OK') csrf_exempt这个装饰器只能给dispatch装才能生效 """ csrf_protect方式全都可以 跟你普通的装饰器装饰CBV一致 """ @method_decorator(csrf_protect,name='post') # 可以 class MyIndex(views.View): @method_decorator(csrf_protect) def dispatch(self, request, *args, **kwargs): return super().dispatch(request,*args,**kwargs) def get(self,request): return render(request,'transfer.html') @method_decorator(csrf_protect) # 可以 def post(self,request): return HttpResponse('OK')
django settings源码剖析
django有两个配置文件
一个是暴露给用户可以配置的
一个是内部全局的(用户配置了就用用户的 用户没有配就用自己的)
obj
obj.name = 'egon' # 全局
obj.name = 'jason' # 局部
先加载全局配置 给对象设置
然后在加载局部配置 再给对象设置
一旦有重复的项 后者覆盖前者
auth模块
auth模块常用方法
如何创建超级用户(root)
python3 manage.py createsuperuser
创建用户:
from django.contrib.auth.models import User User.objects.create(username=username,password=password)
不可用 密码不是加密的
User.objects.create_user(username=username,password=password)
创建普通用户 密码自动加
User.objects.create_superuser(username=username,password=password,email='123@qq.com')
创建超级用户 需要邮箱数据
校验用户名和密码是否正确:
from django.contrib import auth user_obj = auth.authenticate(request,username=username,password=password)
必须传用户名和密码两个参数缺一不能
保存用户登录状态
auth.login(request,user_obj)
只要这句话执行了 后面在任意位置 只要你能拿到request你就可以通过request.user获取到当前登录的用户对象
判断当前用户是否登录
request.user.is_authenticated()
校验原密码是否正确
request.user.check_password(old_password)
修改密码
request.user.set_password(new_password) request.user.save() # 千万不要忘了
注销
auth_logout(request)
校验用户是否登录装饰器
from django.contrib.auth.decorators import login_required 局部配置 @login_required(login_url='/login/') def index(request): pass 全局配置 settings配置文件中 直接配置 LOGIN_URL = '/login/' @login_required def index(request): pass
如果全局配置了 局部也配置 以局部的为准
如何扩展auth_user表字段
方式1
利用一对一外键字段关系
class UserDetail(models.Model): phone = models.BigIntegerField() user = models.OneToOneField(to='User')
方式2
利用继承关系
from django.contrib.auth.models import AbstractUser class Userinfo(AbstractUser): phone = models.BigIntegerField() register_time = models.DateField(auto_now_add=True)
一定要注意 还需要去配置文件中配置
AUTH_USER_MODEL = 'app01.Userinfo' # 应用名.表名
这么写完之后 之前所有的auth模块功能全都以你写的表为准