一、模拟实现中间件的编程思想

(一)impotlib模块

  1. importlib模块可以通过字符串的形式导入模块
  2. importlib模块也支持notify.email的from···import类型
  3. 最小单位只能到文件名,不能用来导入文件中的变量名
# importlib模块(以导入json模块为例)
import importlib
json = importlib.import_module('json') module = importlib.import_module('notify.email')

(二)实现功能的配置使用

  1. 基于Django中间件的思想实现功能的配置使用
  2. 可以通过在settings.py中注释某个字符串来动态取消或增加某个功能的实现
# settings.py
NOTIFY_LIST = [
'notify.email.Email',
'notify.msg.Msg',
'notify.wechat.WeChat',
'notify.qq.Qq',
]
# noyify/eamil.py
class Email(object):
def __init__(self):
pass # 发送邮件需要的前期准备 def send(self,content):
print('邮件通知:%s'%content)
# noyify/msg.py
class Msg(object):
def __init__(self):
pass # 发送短信需要的前期准备 def send(self,content):
print('短信通知:%s'%content)
# noyify/wechat.py
class WeChat(object):
def __init__(self):
pass # 发送微信需要的前期准备 def send(self,content):
print('微信通知:%s'%content)
# noyify/__init__.py
import settings
import importlib def send_all(content):
for path in settings.NOTIFY_LIST:
module_name,cls_name=path.rsplit('.',maxsplit=1) # 因为import最小单位只能到文件,因此需要将文件路径和类名分隔开
module = importlib.import_module(module_name) # 通过importlib导入文件
cls = getattr(module,cls_name) # 通过反射获取文件中类
obj = cls()
obj.send(content)
# start.py
from notify import *
send_all('明天放假')

二、跨站请求伪造CSRF

(一)由来

以钓鱼网站的转账为例:

  1. 做一个假的网站,使得用户填写的对方账户iniput标签没有name属性
  2. 在内部隐藏一个具有name属性input标签,value为自己的账户
  3. 此时提交时,后端获取的目标账户是自己的账户,从而形成钓鱼

因此,CSRF就是为了解决这种问题

  1. 网站在返回用户form表单时,自动隐藏一个input标签,该标签value为一个随机的字符串
  2. 每一个浏览器发送的随机字符串都是独一无二的
  3. 从而解决这种调阅问题

(二)form表单的CSRF

  1. 只需要在表单中写一个{% csrf_token %}
  2. 浏览器中的隐藏input标签中name="csrfmiddlewaretoken"
  3. 每一次刷新,value值都会不一样
<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标签-->
<input type="hidden" name="csrfmiddlewaretoken" value="rJ47FeK9T55wavvVJGY6UxdM1kTMHhTqotGfaXjXIK8Ahz2Uvs02yR9T8bBn5q2D">

(三)ajax中的CSRF

(1)通过data携带

  1. 在html页面任意地方书写{% csrf_token %}
  2. 通过标签查找将随机字符串添加到ajax的data对象中或者直接调用模板语法即可
data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},

data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},

(2)通过headers携带

通过获取返回的cookie中字符串,放置在请求头中

$.ajax({
url: "/cookie_ajax/",
type: "POST",
headers: {"X-CSRFToken": $.cookie('csrftoken')}, // 从Cookie取csrf_token,并设置ajax请求头
data: {"username": "Q1mi", "password": 123456},
success: function (data) {
console.log(data);
}
})

(3)官网提供的文件(推荐用法)

  1. static文件夹下新建一个任意名JS文件(setup.js为例),拷贝以下代码
  2. 在页面中导入该js文件
# jswenjian
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);
}
}
});

(四)CSRF相关的装饰器

  1. 局部:CSRF相关的装饰器用于局部设置或取消CSRF验证
  2. 全局: 通过中间件 django.middleware.csrf.CsrfViewMiddleware 来设置或取消CSRF校验

(1)MTV模型中使用

  1. 需要先导入装饰器
  2. @csrf_protect :设置被装饰函数的CSRF(跨站请求伪造)校验
  3. @csrf_exempt:取消被装饰函数的CSRF(跨站请求伪造)取消
from django.views.decorators.csrf import csrf_exempt,csrf_protect

(2)CBV模型中使用

  1. csrf_protect装饰器CBV中四种装饰器使用方式都可以生效,
  2. csrf_exempt装饰器只能给dispatch装才能生效
# 1. 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') # 2. csrf_exempt这个装饰器只能给dispatch装才能生效
# @method_decorator(csrf_exempt,name='post') # csrf_exempt不支持该方法
@method_decorator(csrf_exempt,name='dispatch') # 生效
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')

三、Django中auth模块

(一)什么是auth模块

  1. auth模块是Django自带的用户认证模块,可以实现包括用户登录、注册、认证、注销、修改密码等功能
  2. 默认使用auth_user表存储用户数据
  3. 使用之前先导入from django.contrib import auth

(二)常用方法

(1)创建用户

  1. create_superuser(): 创建超级用户 ,必要参数username、password、email
  2. create_user():创建普通用户,必要参数username、password
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') # 创建超级用户 需要邮箱数据

(2)校验用户

  • authenticate(): 验证用户名以及密码是否正确 , 需要username 、password两个关键字参数 ,正确返回User对象,否则为空
from django.contrib import auth
user_obj = auth.authenticate(request,username=username,password=password)
# 必须传用户名和密码两个参数缺一不能

(3)登录保存

  • login(HttpRequest, user):用户登录并保存状态,保存后可以通过request.user中获取当前登录用户对象
auth.login(request,user_obj)
# 只要这句话执行了 后面在任意位置 只要你能拿到request你就可以通过request.user获取到当前登录的用户对象

(4)是否登录

  • is_authenticated(): 判断当前请求是否通过了认证
request.user.is_authenticated()

(5)检验密码

  • check_password(password): 检查密码是否正确的方法,需要提供当前请求用户的密码 ,返回布尔值
request.user.check_password(old_password)

(6)修改密码

  • set_password(password):设置密码,修改完之后一定记得使用save保存
request.user.set_password(new_password)
request.user.save() # 千万不要忘了

(7)注销

  • logout(request): 清除当前请求的全部session信息, 无返回值
auth.logout(request)

(8)登录检验装饰器

  • login_requierd(): 一个登录校验的装饰器,可以添加变量login_url指定没有登录情况下跳转的页面

    1. 局部配置:直接在括号内添加页面地址
    2. 全局配置:settings文件中配置LOGIN_URL参数
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
# 如果全局配置了 局部也配置 以局部的为准

(9)User对象的方法

  1. i s_staff : 用户是否拥有网站的管理权限
  2. is_active : 是否允许用户登录, 设置为 False,可以在不删除用户的前提下禁止用户登录。

(三)扩展默认的auth_user表

(1)一对一外键

通过一对一外键字段关系扩展字段

class UserDetail(models.Model):
phone = models.BigIntegerField()
user = models.OneToOneField(to='User')

(2)继承

  1. 自定义一个继承内置的AbstractUser的Model类 (需要先导入)
  2. settings配置文件中配置AUTH_USER_MODEL参数(应用名.表名)
# module.py
from django.contrib.auth.models import AbstractUser class Userinfo(AbstractUser):
phone = models.BigIntegerField()
register_time = models.DateField(auto_now_add=True) # settings.py
AUTH_USER_MODEL = 'app01.Userinfo' # 应用名.表名

四、Django中settings源码

  1. Django中有两个配置文件,一个内部全局的,一个用户自定义
  2. 如果用户配置了,就使用该配置,否则使用内部全局设置

实现思路:先加载全局配置给对象设置,然后在加载局部配置 再给对象设置,一旦有重复的项 后者覆盖前者

五、文件插拔式设计

基于settings源码设计思想启发,实现文件插拔式设计

# conf/settings.py
NAME = '我是暴露给用户的自定义配置'
# lib/conf/globa_settings.py
NAME = '我是项目默认的配置文件'
# lib/conf/__init__.py import importlib
from lib.conf import global_settings
import os class Settings(object):
def __init__(self):
for name in dir(global_settings):
if name.isupper():
setattr(self, name, getattr(global_settings, name))
# 获取暴露给用户的配置文件字符串路径
module_path = os.environ.get('xxx')
md = importlib.import_module(module_path) # md = settings
for name in dir(md):
if name.isupper():
k = name
v = getattr(md,name)
setattr(self,k,v) settings = Settings()
# start.py
import os
import sys BASE_DIR = os.path.dirname(__file__)
sys.path.append(BASE_DIR) if __name__ == '__main__':
# os.environ.setdefault('xxx','conf.settings')
os.environ['xxx'] = 'conf.settings' # environ是一个字符串所对应环境的映像对象
from lib.conf import settings
print(settings.NAME)

CSRF与auth模块的更多相关文章

  1. (day59)十一、CSRF、Auth模块、impotlib模块、settings源码

    目录 一.模拟实现中间件的编程思想 (一)impotlib模块 (二)实现功能的配置使用 二.跨站请求伪造CSRF (一)由来 (二)form表单的CSRF (三)ajax中的CSRF (1)通过da ...

  2. django 之csrf、auth模块及settings源码、插拔式设计

    目录 基于django中间件拷贝思想 跨站请求伪造简介 跨站请求伪造解决思路 方式1:form表单发post请求解决方法 方式2:ajax发post请求解决方法 csrf相关的两个装饰器 csrf装饰 ...

  3. 1205 CSRF跨站请求与django中的auth模块使用

    目录 今日内容 昨日回顾 基于配置文件的编程思想 importlib模块 简单代码实现 跨站请求伪造csrf 1. 钓鱼网站 如何实现 模拟该现象的产生 2. 解决问题 解决 {% csrf_toke ...

  4. Django-中间件-csrf扩展请求伪造拦截中间件-Django Auth模块使用-效仿 django 中间件配置实现功能插拔式效果-09

    目录 昨日补充:将自己写的 login_auth 装饰装在 CBV 上 django 中间件 django 请求生命周期 ***** 默认中间件及其大概方法组成 中间件的执行顺序 自定义中间件探究不同 ...

  5. 跨站请求伪造(csrf),django的settings源码剖析,django的auth模块

    目录 一.跨站请求伪造(csrf) 1. 什么是csrf 2. 钓鱼网站原理 3. 如何解决csrf (1)思路: (2)实现方法 (3)实现的具体代码 3. csrf相关的装饰器 (1)csrf_p ...

  6. Django对中间件的调用思想、csrf中间件详细介绍、Django settings源码剖析、Django的Auth模块

    目录 使用Django对中间件的调用思想完成自己的功能 功能要求 importlib模块介绍 功能的实现 csrf中间件详细介绍 跨站请求伪造 Django csrf中间件 form表单 ajax c ...

  7. Django之csrf中间件及auth模块使用

    目录 一.基于配置文件的编程思想 1. importlib 模块 2. 配置文件 二.跨站请求伪造(csrf) 1.csrf简介以及由来 2.Django中的csrf中间件如何使用 2.1 普通for ...

  8. Django CBV装饰器 中间件 auth模块 CSRF跨站请求

    CBV添加装饰器 给CBV添加装饰器有三种方法,三种方法都需要导入模块: from django.utils.decorators import method_decorator 第一种直接在方法上面 ...

  9. csrf跨站请求、相关装饰器、auth模块使用

    昨日内容回顾 django操作cookie和session # 作用:就是保存用户信息,保存一系列数据,还可以做缓存 保留一段时间 # session是基于cookie工作的 1. 数据是保存在服务端 ...

随机推荐

  1. ArcGIS Server10.4安装教程

    准备内容 安装环境:win10*64位专业版 安装文件:ArcGIS_Server_Ent_Windows_1041_150998.iso 破解文件:Lic10.4.1.ecp #安装Server前, ...

  2. jquery浅复制和深复制区别

    jquery浅复制和深复制区别

  3. word2vec:CBOW和skip-gram模型

    1.CBOW模型 之前已经解释过,无论是CBOW模型还是skip-gram模型,都是以Huffman树作为基础的.值得注意的是,Huffman树中非叶节点存储的中间向量的初始化值是零向量,而叶节点对应 ...

  4. SpringCloud Alibaba微服务实战三 - 服务调用

    导读:通过前面两篇文章我们准备好了微服务的基础环境并让accout-service 和 product-service对外提供了增删改查的能力,本篇我们的内容是让order-service作为消费者远 ...

  5. Python Kite 使用教程 轻量级代码提示

    1: 概述 今天升级annacoda 插件 spyder  (4.0.0 )的时候 提示安装kite ,这是什么玩意? 下载下来试一试? 原来:就是一个代码提示插件.. 说白了" 就是让开发 ...

  6. Linux下搭建web服务

    第一:安装java 第二:安装tomcat 第三:部署程序 第一:安装java 下载地址: http://www.oracle.com/technetwork/java/javase/download ...

  7. 【JMX】jmx结合jmx_exporter实现promethues监控

    JMX JMX的全称为Java Management Extensions. 顾名思义,是管理Java的一种扩展.这种机制可以方便的管理.监控正在运行中的Java程序.常用于管理线程,内存,日志Lev ...

  8. 谁说微服务是Spring Cloud的独角戏?Service Mesh了解一下?

    Service Mesh 的概念自 2017 年初提出之后,受到了业界的广泛关注,作为微服务的下一代发展架构在社区迅速发酵,并且孵化出了诸如 Istio 等广受业界关注的面向于云原生 (Cloud N ...

  9. MySQL的存储(二、创建表并插入)

    创建表 首先创建一个 spiders的数据库 cursor.execute("create database spiders default character set utf8" ...

  10. Internet History,Technology,and Security - Dawn of Electronic Computing(Week 1)

    一 War Time Computing and Communication 讲到电子计算机,你不得不提起第二次世界大战,虽说二战是人类历史上史无前例的大灾难,不过从某种程度来说,它确实促进了社会的发 ...