• Django前后端分离跨域请求问题


    一、问题背景

      之前使用django+vue进行前后端分离碰到跨域请求问题,跨域(域名或者端口不同)请求问题的本质是由于浏览器的同源策略导致的,当请求的响应不是处于同一个域名和端口下,浏览器不会接受响应,同源策略也是浏览器针对请求的安全问题所作出的一种保护行为。针对跨域问题,可以有下面的解决方式:

    • JSONP方式
    • 自定义中间件,设置响应头
    • 使用django-cors-headers包

    二、解决方式

    (一)自定义中间件

      JSONP本质上是利用html的一些不受同源策略影响的标签属性src,例如:<a>、<img>、<script>等标签的src属性,从而实现跨域请求,但是这种方法只支持GET的请求方式,这里暂不做过多讨论,主要说自定义中间件以及利用django-cors-headers包来实现跨域。

    1、自定义中间件

    class MiddlewareMixin(object):
        def __init__(self, get_response=None):
            self.get_response = get_response
            super(MiddlewareMixin, self).__init__()
    
        def __call__(self, request):
            response = None
            if hasattr(self, 'process_request'):
                response = self.process_request(request)
            if not response:
                response = self.get_response(request)
            if hasattr(self, 'process_response'):
                response = self.process_response(request, response)
            return response
    
    class CORSMiddleware(MiddlewareMixin):
    
        def process_response(self,request,response):
            # 添加响应头
            # 允许相应的域名来访问,多个域名中间以逗号隔开,如果全部可使用'*'
            response['Access-Control-Allow-Origin'] = "*"
            # 允许携带的请求头,多个中间以逗号隔开
            response['Access-Control-Allow-Headers'] = "Content-Type"
            # 允许发送的请求方式
            response['Access-Control-Allow-Methods'] = "DELETE,PUT"
            return response

    2、注册中间件(在settings文件中注册)

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
         ...
         ...
        'crm.utils.cors.CORSMiddleware' #跨域中间件
    ]

    (二)CORS(Cross-Origin Resource Sharing)

    1、安装django-cors-headers包

    pip install django-cors-headers #在对应的开发环境中安装

    2、修改settings文件

    • 注册应用
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        ...'django.contrib.staticfiles',
        'corsheaders',#放在新建应用之前
        'rest_framework',
        ...'crm'
    ]
    • 中间件注册
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'corsheaders.middleware.CorsMiddleware',  # 注意顺序,放在此处
        'django.middleware.common.CommonMiddleware',
         ...
    ]
    • 其它设置
    CORS_ORIGIN_ALLOW_ALL = True  #允许所有的请求,或者设置CORS_ORIGIN_WHITELIST,二选一
    CORS_ALLOW_HEADERS = ('*') #允许所有的请求头
    CORS_ALLOW_CREDENTIALS = True  # 允许携带cookie,前端需要携带cookies访问后端时,需要设置withCredentials: true

    这样就可以进行跨域使用了。

      但是大多数站点将需要利用Django提供跨站点请求伪造保护CORS和CSRF是分开的,并且Django无法使用您的CORS配置免除网站Referer对安全请求所做检查。做到这一点的方法是使用其CSRF_TRUSTED_ORIGINS设置

    3、CSRF整合

    #1、CSRF_TRUSTED_ORIGINS  设置
    CORS_ORIGIN_WHITELIST  = [
         ' http://read.only.com '' http://change.allowed.com ',
    ] #不需要CORS_ORIGIN_ALLOW_ALL=True的设置
    
    CSRF_TRUSTED_ORIGINS  = [
         ' change.allowed.com ',
    ]
    
    #2、中间件设置
    #启用此功能在django.middleware.csrf.CsrfViewMiddleware后,还应添加#corsheaders.middleware.CorsPostCsrfMiddleware
    MIDDLEWARE_CLASSES  = [
         ... 
        ' corsheaders.middleware.CorsMiddleware ',
         ... 
        ' django.middleware.csrf.CsrfViewMiddleware ''corsheaders.middleware.CorsPostCsrfMiddleware ',
         ... 
    ]

    详情参考官方文档https://github.com/adamchainz/django-cors-headers

  • 相关阅读:
    第一个ADO.NET连接SQl server数据库
    Mysql编码
    SNMP协议报文分析
    物理层计算
    随机产生数组
    c#排序
    c#计算一段代码的时间复杂度
    jwt认证
    drf三大组件之频率认证组件
    drf三大组件之认证组件与权限组件
  • 原文地址:https://www.cnblogs.com/shenjianping/p/11718925.html
Copyright © 2020-2023  润新知