Django 安全与验证
2022-07-08 本文已影响0人
李霖弢
CORS
安装
pip install django-cors-headers
配置
CORS_ORIGIN_ALLOW_ALL = True # 默认为False。为True时白名单不生效
CORS_ORIGIN_WHITELIST = [] # 白名单,默认为[]
CORS_ORIGIN_REGEX_WHITELIST = [] # 正则白名单
CORS_ALLOW_CREDENTIALS = False # 是否允许跨站点cookie。默认为False
# 允许请求类型列表,此为默认值
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
# 允许的非标准HTTP头列表,此为默认值
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
# 注册
INSTALLED_APPS = (
'corsheaders',
)
# 添加中间件
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', #最好添加至第一行
]
CSRF
用于防止 post / put / delete 请求的跨站请求伪造,类似于一个一次性的token。
在服务端返回给客户端数据时(所有请求),设置客户端cookie的csrftoken
字段,客户端下次请求时应带上其内容,供django校验
# 全局开启CSRF
MIDDLEWARE = [
'django.middleware.csrf.CsrfView.Middleware',
]
# 白名单
CSRF_TRUSTED_ORIGINS = [
'change.allowed.com',
]
# views.py
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_protect # 单独启用CSRF
@csrf_exempt # 单独禁用CSRF
SQL注入
ORM模型天生避免了SQL注入,唯一的漏洞是使用.extra()
方法时,因此要注意不要使用动态拼接 SQL 的方式,而是将 SQL 语句和参数分开放
# 存在SQL注入漏洞代码
name = 'Joe' # 如果first_name中有SQL特定字符就会出现漏洞
User.objects.all().extra(where=["name='%s' and password='%s'" % (name, password)])
# 正确方式
User.objects.all().extra(where=["name='%s' and password='%s'"], params=[name, password])
Cookie
在视图中,可以为返回值添加cookie信息
def xxxx(request, *args, **kwargs):
# ...
rep = HttpResponse(...)
# 或者
rep = render(request, ...)
# 或者
rep = redirect( ...)
# 两种设置cookie的方法,一种不加salt,另一个加salt
rep.set_cookie(key, value,...)
rep.set_signed_cookie(key, value, salt='加密盐', max_age=None, ...)
return rep
则下次收到浏览器请求时,可以在request中获取cookie
request.COOKIES['key']
request.COOKIES.get['key']
# 对应前面使用前面加密的cookie
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
Session
配置后启用,可以在视图中通过request.session
读写session,该属性是SESSION_ENGINE 配置中 SessionStore 类的实例,继承自 django.contrib.sessions.backends.base.SessionBase
类,具有如下方法:
- get(self, key, default=None):获取 Session 中的 key 值对应的 value。这种方式比较推荐。因为在 key 不存在时可以取默认值,而request.session[key] 这样的写法在 key 不存在时会抛出异常;
- pop(key, default=__not_given):返回 Session 中 key 对应的 value 值,并将其从 Session 中删除;
- keys():返回 Session 中所有的 key 值
- setdefault(key, value):给某个 key 设置对应的默认 value
- set_expiry(value):给 Session 设置对应的过期时间;
# views.py
if request.session.get('has_login', False):
return HttpResponse('已经登陆成功,无需再次登陆')
request.session['has_login'] = True
# 设置10s后过期
request.session.set_expiry(10)
# settings.py
MIDDLEWARE = [
# ...
'django.contrib.sessions.middleware.SessionMiddleware',
# ...
]
INSTALLED_APPS = [
# 启用 sessions 应用
'django.contrib.sessions',
]
# 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 默认引擎
# 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
# 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
SESSION_CACHE_ALIAS = 'default'
# 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'
# 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
SESSION_FILE_PATH = None
# 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
# 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
# Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_NAME = "sessionid"
# Session的cookie保存的路径(默认)
SESSION_COOKIE_PATH = "/"
# Session的cookie保存的域名(默认)
SESSION_COOKIE_DOMAIN = None
# 是否Https传输cookie(默认)
SESSION_COOKIE_SECURE = False
# 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_HTTPONLY = True
# Session的cookie失效日期(2周)(默认)
SESSION_COOKIE_AGE = 1209600
# 是否关闭浏览器使得Session过期(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
# 是否每次请求都保存Session,默认修改之后才保存(默认)
SESSION_SAVE_EVERY_REQUEST = False