django入门菜鸟教程:csrf跨站请求伪造与 auth认证模块
csrf跨站请求伪造
1.简介
钓鱼网站:跟官方网站一样的网址页面,用户在该页面上转账,受益人确不是自己想要转账给的那个人。
2.模拟
一台计算机上两个服务端不同端口启动,将钓鱼网站的提交地址改为正规网站的地址
3.预防
csrf策略:通过在返回页面上添加独一无二的表示信息来区分正规网站和钓鱼网站的请求。
csrf操作
1.form表单
<form action="" method="post">
{% csrf_token %}
<p>username:
<input type="text" name="username">
</p>
<p>password:
<input type="text" name="password">
</p>
<input type="submit">
</form>
正常情况下,form表单发送post请求,会报403 Forbidden 错误,在表单内加上{% csrf_token %}(跨站请求伪造)便不会报错。此时浏览器的f12审查元素,我们发现{% csrf_token %}已经变成了一个隐藏的input框,它的属性 name = 'csrfmiddlewaretoken' value = 一串看不懂的密钥,这个密钥就是上文所说的独一无二的表示信息。当然这个值每次都不一样。
2.ajax
<script>
$('#d1').click(function () {
$.ajax({
url: '',
type: 'post',
data: {
'username': $('input[name="username"]').val(),
'password': $('input[name="password"]').val(),
'csrfmiddlewaretoken': {{ csrf_token }}
},
success: function () {
}
})
})
</script>
3.js脚本
参照网站 https://docs.djangoproject.com/en/1.11/ref/csrf/
csrf相关装饰器
1.当整个网站默认都不校验csrf 但是局部视图函数需要校验 如何处理
2.当整个网站默认都要校验csrf 但是局部视图函数不需要校验 如何处理
FBV:
@csrf_protect # 校验csrf
@csrf_exempt # 不校验csrf
def home(request):
return render(request, 'home.html')
CBV:
针对CBV不能直接在方法上添加装饰器,需要借助于专门添加装饰器的方法
方式1:
class MyView(views.View):
@method_decorator(csrf_protect) # 指名道姓地添加,一个装饰器只能作用于视图类中的一个方法
def post(self, request):
return HttpResponse('from MyView post')
方式2:
@method_decorator(csrf_protect, name='post') # 指名道姓地添加,效果同上
class MyView(views.View):
def post(self, request):
return HttpResponse('from MyView post')
方式3:
class MyView(views.View):
@method_decorator(csrf_protect) # 重写dispetch方法,给视图类下的所有函数都添加装饰器
def dispatch(self, request, *args, **kwargs):
super(MyView, self).dispatch(request, *args, **kwargs)
def post(self, request):
return HttpResponse('from MyView post')
'针对csrf_exempt只有第三种方法有效,针对其他装饰器,上面三种方式都有效'
auth认证模块
django执行数据库迁移命令之后会产生一个auth_user表,该表可以配合auth模块做用户相关的功能:登录注册、修改密码、注销等等。此外该表还是django admin后台管理功能默认使用的表。
django admin后台管理员账号创建
'python manage.py createsuperuser'
auth模块常见功能
1.创建用户
Tools --> Run manage.py Task --> createsuperuser
2.校验用户名密码是否正确
from django.contrib import auth
auth.authenticate(request, username=username, password=password) # 先对密码做加密,然后再比对。
3.保存用户登录状态
auth.login(request, user_obj) # 此方法自动在session表中添加一个session信息
'代码实现:'
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)
print(user_obj) # jason
# 保存用户登录状态
auth.login(request, user_obj)
return render(request, 'login.html')
4.获取当前登录的用户对象
request.user
此方法要么返回用户对象(登陆成功),要么返回匿名用户(登录不成功)
5.判断当前用户是否登录
request.user.is_authenticated
此方法返回布尔值
'代码实现:'
def get_user(request):
print(request.user) # jason 登录状态
print(request.user.is_authenticated) # True
print(request.user) # AnonymousUser 未登录状态
print(request.user.is_authenticated) # False
return HttpResponse()
6.校验用户登录装饰器
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/') # login_url可以控制未登录时跳转的网址
def home(request):
return render(request, 'home.html')
跳转局部配置:(单个视图函数有效)
login_required(login_url='/login/')
跳转全局配置:(整个django项目有效)
settings.py ---> LOGIN_URL = '/login/'
7.校验密码是否正确(可以用于修改密码校验)
is_login = request.user.check_password(old_password) # 括号内跟需要校验的密码
该方法有返回值 True/False
8.修改密码
request.user.set_password(new_passowrd)
request.user.save() # 修改之后记得保存
9.注销登录(本质是清除cookie和session)
auth.logout(request)
auth拓展表字段
1.models.py
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
# 编写AbstractUser类中没有的字段 不能冲突
phonre = models.BigIntegerField()
2.setting.py
AUTH_USER_MODEL = 'app01.MyUser'
功能的插拔式设计
"""
模块的导入
import 句式
from ... import ... 句式
"""
1.简单的函数式封装
2.配置文件插拔式设计
作者:爱新觉罗吉星
来源:稀土掘金
THE END