• 使用Python进行页面开发——Django的其他核心功能


    目录

    一、静态文件

    配置静态文件

    二、Csrf

    csrf的使用

    取消保护

    保护原理

    三、状态保持

    开启session

    使用session

    四、中间件

    验证用户是否登陆示例

    配置中间件

    五、使用Django中提供的密码方案

    python中的MD5加密


    一、静态文件

    项目中的CSS、图片、js都是静态文件

    配置静态文件

    1.在settings 文件中定义静态内容

    1. STATIC_URL = '/static/'
    2. STATICFILES_DIRS = [
    3. os.path.join(BASE_DIR, 'static'),
    4. ]

    2.在项目根目录下创建static目录,再创建当前应用名称的目录

    mysite/static/myapp/
    

    3.在模板中可以使用硬编码

    /static/my_app/myexample.jpg
    

    4.在模板中可以使用static编码

    1. { % load static from staticfiles % }
    2. "{ % static "my_app/myexample.jpg" % }" alt="My image"/>

    二、Csrf

    CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本XSS,但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性

    CSRF中间件和模板标签为防止跨站点请求伪造提供了易用的保护

    当恶意网站包含链接,表单按钮或某些旨在在您的网站上执行某些操作的JavaScript时,会使用在浏览器中访问恶意网站的登录用户的凭据进行此类攻击。

    还介绍了一种相关攻击类型,即“登录CSRF”,攻击网站欺骗用户的浏览器,以便使用其他人的凭证登录到网站。

    csrf的使用

    在django的模板中,提供了防止跨站攻击的方法,使用步骤如下:

    • step1:在settings.py中启用'django.middleware.csrf.CsrfViewMiddleware'中间件,此项在创建项目时,默认被启用
    • step2:在HTML的表单中添加标签
      1. <form>
      2. { % csrf_token % }
      3. ...
      4. form>

    取消保护

    如果某些视图不需要保护,可以使用装饰器csrf_exempt,模板中也不需要写标签,修改csrf2的视图如下 from django.views.decorators.csrf import csrf_exempt

    1. @csrf_exempt
    2. def csrf2(request):
    3. uname=request.POST['uname']
    4. return render(request,'booktest/csrf2.html',{'uname':uname})
    5. 运行上面的两个请求,发现都可以请求

    保护原理

    加入标签后,可以查看源代码,发现多了如下代码

    <input type='hidden' name='csrfmiddlewaretoken' value='nGjAB3Md9ZSb4NmG1sXDolPmh3bR2g59' />
    
    • 在浏览器的调试工具中,通过network标签可以查看cookie信息

    • 本站中自动添加了cookie信息,如下图csrf3

    • 查看跨站的信息,并没有cookie信息,即使加入上面的隐藏域代码,发现又可以访问了

    • 结论:django的csrf不是完全的安全

    • 当提交请求时,中间件'django.middleware.csrf.CsrfViewMiddleware'会对提交的cookie及隐藏域的内容进行验证,如果失败则返回403错误

    Ajax CSRF 认证

    GET 请求不需要 CSRF 认证,POST 请求需要正确认证才能得到正确的返回结果。

    如果使用Ajax调用的时候,就要麻烦一些。需要注意以下几点:

    • 在视图中使用render (而不要使用 render_to_response)
    • 使用 jQuery 的 ajax 或者 post 之前 加入这个 js 代码

      1. jQuery(document).ajaxSend(function(event, xhr, settings) {
      2. function getCookie(name) {
      3. var cookieValue = null;
      4. if (document.cookie && document.cookie != '') {
      5. var cookies = document.cookie.split(';');
      6. for (var i = 0; i < cookies.length; i++) {
      7. var cookie = jQuery.trim(cookies[i]);
      8. // Does this cookie string begin with the name we want?
      9. if (cookie.substring(0, name.length + 1) == (name + '=')) {
      10. cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
      11. break;
      12. }
      13. }
      14. }
      15. return cookieValue;
      16. }
      17. function sameOrigin(url) {
      18. // url could be relative or scheme relative or absolute
      19. var host = document.location.host; // host + port
      20. var protocol = document.location.protocol;
      21. var sr_origin = '//' + host;
      22. var origin = protocol + sr_origin;
      23. // Allow absolute or scheme relative URLs to same origin
      24. return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
      25. (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
      26. // or any other URL that isn't scheme relative or absolute i.e relative.
      27. !(/^(\/\/|http:|https:).*/.test(url));
      28. }
      29. function safeMethod(method) {
      30. return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
      31. }
      32. if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
      33. xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
      34. }
      35. });
    • 或者 更为优雅简洁的代码(不能写在 .js 中,要直接写在模板文件中):

      1. $.ajaxSetup({
      2. data: {csrfmiddlewaretoken: '{ { csrf_token } }' },
      3. });

    这样之后,就可以像原来一样的使用 jQuery.ajax() 和 jQuery.post()了

    三、状态保持

    • HTTP协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状
    • 客户端与服务器端的一次通信,就是一次会话
    • 实现状态保持的方式:在客户端或服务器端存储与会话有关的数据
    • 存储方式包括cookie、session,会话一般指session对象
    • 使用cookie,所有数据存储在客户端,注意不要存储敏感信息
    • 推荐使用sesison方式,所有数据存储在服务器端,在客户端cookie中存储session_id
    • 状态保持的目的是在一段时间内跟踪请求者的状态,可以实现跨页面访问当前请求者的数据
    • 注意:不同的请求者之间不会共享这个数据,与请求者一一对应

    开启session

    • 使用django-admin startproject创建的项目默认启用
    • 禁用会话:删除下面指定的两个值,禁用会话将节省一些性能消耗
    • Django 中session需要依赖数据库,因此需要确认数据库中是否存在 与session相关的 表
    • 在settings.py文件中

      1. * 项INSTALLED_APPS列表中添加:
      2. * 'django.contrib.sessions',
      3. * 项MIDDLEWARE_CLASSES列表中添加:
      4. * 'django.contrib.sessions.middleware.SessionMiddleware',

    使用session

    • 启用会话后,每个HttpRequest对象将具有一个session属性,它是一个类字典对象
    • get(key, default=None):根据键获取会话的值
    • clear():清除所有会话
    • flush():删除当前的会话数据并删除会话的Cookie
    • del request.session['member_id']:删除会话
    • 示例:

      1. #session设置
      2. request.session[key] = value
      3. #session获取
      4. request.session.get(key,default=Node)
      5. #session删除
      6. # 删除单个key 不存在时报错
      7. del request.session['a']
      8. #清除所有会话,但不会删除数据
      9. request.session.clear()
      10. #删除当前的会话数据
      11. request.session.flush()

    四、中间件

    • 中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出
    • 激活:添加到Django配置文件中的MIDDLEWARE_CLASSES元组中
    • 使用中间件,可以干扰整个处理过程,每次请求中都会执行中间件的这个方法

    验证用户是否登陆示例

    在应用中创建AdminLoginMiddleware.py文件

    1. from django.shortcuts import render
    2. from django.http import HttpResponse
    3. import re
    4. class AdminLoginMiddleware:
    5. def __init__(self, get_response):
    6. self.get_response = get_response
    7. # One-time configuration and initialization.
    8. def __call__(self, request):
    9. # 检测当前的请求是否已经登录,如果已经登录,.则放行,如果未登录,则跳转到登录页
    10. # 获取当前用户的请求路径 /admin/开头 但不是 /admin/login/ /admin/dologin/ /admin/verifycode
    11. urllist = ['/admin/login','/admin/dologin','/admin/vcode']
    12. # 判断是否进入了后台,并且不是进入登录页面
    13. if re.match('/admin/',request.path) and request.path not in urllist:
    14. # 检测session中是否存在 adminlogin的数据记录
    15. if request.session.get('Vuser','') == '':
    16. # 如果在session没有记录,则证明没有登录,跳转到登录页面
    17. return HttpResponse('')
    18. response = self.get_response(request)
    19. return response

    配置中间件

    在settings.py文件中修改MIDDLEWARE_CLASSES选项

    1. MIDDLEWARE = [
    2. 'django.middleware.security.SecurityMiddleware',
    3. 'django.contrib.sessions.middleware.SessionMiddleware',
    4. 'django.middleware.common.CommonMiddleware',
    5. 'django.middleware.csrf.CsrfViewMiddleware',
    6. 'django.contrib.auth.middleware.AuthenticationMiddleware',
    7. 'django.contrib.messages.middleware.MessageMiddleware',
    8. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    9. #自定义的中间件
    10. 'myadmin.AdminMiddleware.AdminLoginMiddleware'
    11. ]

    五、使用Django中提供的密码方案

    django.contrib.auth.hashers模块提供了一组函数来创建和验证散列密码。您可以独立于User模型使用它们。

    1. # from django.contrib.auth.hashers import make_password, check_password
    2. # 对密码进行加密操作
    3. # upass = make_password(request.POST['password'], None, 'pbkdf2_sha256')
    4. # upass = check_password('1234567','pbkdf2_sha256$36000$197nqXM6yxYv$Zxh/Vsns8qszkvUmY81BgrjCeLPXhCHLEilP6VO+Rnc=')

    python中的MD5加密

    1. #获取密码并md5
    2. import hashlib
    3. m = hashlib.md5()
    4. m.update(bytes(request.POST['password'],encoding="utf8"))
    5. print(m.hexdigest())

     

     

     

     

  • 相关阅读:
    SpringCloud微服务的监控器,Actuator
    悬架模糊控制
    分布式系统的一致性与共识(1)-综述
    centos7.9安装openssl1.1.1
    如何简单挖掘公益SRC?
    教程分享:如何将微信公众号变成淘宝客查券返利机器人自动赚佣金?
    【区块链 | 智能合约】Ethereum源代码(9)- 以太坊P2P协议接收广播的处理和Fetcher源码分析
    Linux之操作文件命令
    在 Python 中实现 DBSCAN
    组合索引实例
  • 原文地址:https://blog.csdn.net/weixin_63994459/article/details/126145417