标签归档:cors

在简单的HTTP服务器上启用访问控制

问题:在简单的HTTP服务器上启用访问控制

对于非常简单的HTTP服务器,我具有以下shell脚本:

#!/bin/sh

echo "Serving at http://localhost:3000"
python -m SimpleHTTPServer 3000

我想知道我怎么可以启用或添加CORS标题喜欢Access-Control-Allow-Origin: *到这台服务器?

I have the following shell script for a very simple HTTP server:

#!/bin/sh

echo "Serving at http://localhost:3000"
python -m SimpleHTTPServer 3000

I was wondering how I can enable or add a CORS header like Access-Control-Allow-Origin: * to this server?


回答 0

不幸的是,简单的HTTP服务器是如此简单,以至于它不允许任何自定义,尤其是不允许其发送的标头。但是,您可以使用的大部分内容自己创建一个简单的HTTP服务器SimpleHTTPRequestHandler,而只需添加所需的标头即可。

为此,只需创建一个文件simple-cors-http-server.py(或其他文件),然后根据所使用的Python版本,将以下代码之一放入其中。

然后,您可以执行操作python simple-cors-http-server.py,它将启动修改后的服务器,该服务器将为每个响应设置CORS标头。

shebang置于顶部,使该文件可执行并放入PATH,您也可以使用它运行它simple-cors-http-server.py

Python 3解决方案

Python 3使用SimpleHTTPRequestHandlerHTTPServerhttp.server模块运行服务器:

#!/usr/bin/env python3
from http.server import HTTPServer, SimpleHTTPRequestHandler, test
import sys

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    test(CORSRequestHandler, HTTPServer, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)

Python 2解决方案

Python 2使用SimpleHTTPServer.SimpleHTTPRequestHandlerBaseHTTPServer模块来运行服务器。

#!/usr/bin/env python2
from SimpleHTTPServer import SimpleHTTPRequestHandler
import BaseHTTPServer

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    BaseHTTPServer.test(CORSRequestHandler, BaseHTTPServer.HTTPServer)

Python 2和3解决方案

如果您需要同时兼容Python 3和Python 2,则可以使用在两个版本中都可以使用的多语言脚本。它首先尝试从Python 3位置导入,否则回落到Python 2:

#!/usr/bin/env python
try:
    # Python 3
    from http.server import HTTPServer, SimpleHTTPRequestHandler, test as test_orig
    import sys
    def test (*args):
        test_orig(*args, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)
except ImportError: # Python 2
    from BaseHTTPServer import HTTPServer, test
    from SimpleHTTPServer import SimpleHTTPRequestHandler

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    test(CORSRequestHandler, HTTPServer)

Unfortunately, the simple HTTP server is really that simple that it does not allow any customization, especially not for the headers it sends. You can however create a simple HTTP server yourself, using most of SimpleHTTPRequestHandler, and just add that desired header.

For that, simply create a file simple-cors-http-server.py (or whatever) and, depending on the Python version you are using, put one of the following codes inside.

Then you can do python simple-cors-http-server.py and it will launch your modified server which will set the CORS header for every response.

With the shebang at the top, make the file executable and put it into your PATH, and you can just run it using simple-cors-http-server.py too.

Python 3 solution

Python 3 uses SimpleHTTPRequestHandler and HTTPServer from the http.server module to run the server:

#!/usr/bin/env python3
from http.server import HTTPServer, SimpleHTTPRequestHandler, test
import sys

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    test(CORSRequestHandler, HTTPServer, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)

Python 2 solution

Python 2 uses SimpleHTTPServer.SimpleHTTPRequestHandler and the BaseHTTPServer module to run the server.

#!/usr/bin/env python2
from SimpleHTTPServer import SimpleHTTPRequestHandler
import BaseHTTPServer

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    BaseHTTPServer.test(CORSRequestHandler, BaseHTTPServer.HTTPServer)

Python 2 & 3 solution

If you need compatibility for both Python 3 and Python 2, you could use this polyglot script that works in both versions. It first tries to import from the Python 3 locations, and otherwise falls back to Python 2:

#!/usr/bin/env python
try:
    # Python 3
    from http.server import HTTPServer, SimpleHTTPRequestHandler, test as test_orig
    import sys
    def test (*args):
        test_orig(*args, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)
except ImportError: # Python 2
    from BaseHTTPServer import HTTPServer, test
    from SimpleHTTPServer import SimpleHTTPRequestHandler

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    test(CORSRequestHandler, HTTPServer)

回答 1

尝试其他替代方法,例如http-server

由于SimpleHTTPServer并不是真正要部署到生产环境的服务器,因此我在这里假设您对使用哪种工具并不在乎,只要它能够http://localhost:3000通过简单的方式在CORS标头中公开文件即可命令行

# install (it requires nodejs/npm)
npm install http-server -g

#run
http-server -p 3000 --cors

需要HTTPS吗?

如果您需要在本地使用https,也可以尝试 caddycertbot


您可能会发现有用的一些相关工具

  • ngrok:运行时ngrok http 3000,它将创建一个https://$random.ngrok.com允许任何人访问您的http://localhost:3000服务器的URL 。它可以向世界展示您计算机本地运行的内容(包括本地后端/ API)

  • localtunnel:与ngrok几乎相同

  • 现在:运行时now,它将在线上传您的静态资产并将其部署到https://$random.now.sh。除非您另有决定,否则它们将永远保持在线状态。由于差异,部署速度很快(第一个部署除外)。现在适用于生产前端/ SPA代码部署。它还可以部署Docker和NodeJS应用程序。它不是真正的免费,但他们有免费计划。

Try an alternative like http-server

As SimpleHTTPServer is not really the kind of server you deploy to production, I’m assuming here that you don’t care that much about which tool you use as long as it does the job of exposing your files at http://localhost:3000 with CORS headers in a simple command line

# install (it requires nodejs/npm)
npm install http-server -g

#run
http-server -p 3000 --cors

Need HTTPS?

If you need https in local you can also try caddy or certbot


Some related tools you might find useful

  • ngrok: when running ngrok http 3000, it creates an url https://$random.ngrok.com that permits anyone to access your http://localhost:3000 server. It can expose to the world what runs locally on your computer (including local backends/apis)

  • localtunnel: almost the same as ngrok

  • now: when running now, it uploads your static assets online and deploy them to https://$random.now.sh. They remain online forever unless you decide otherwise. Deployment is fast (except the first one) thanks to diffing. Now is suitable for production frontend/SPA code deployment It can also deploy Docker and NodeJS apps. It is not really free, but they have a free plan.


回答 2

我遇到了同样的问题,并提出了以下解决方案:

class Handler(SimpleHTTPRequestHandler):
    def send_response(self, *args, **kwargs):
        SimpleHTTPRequestHandler.send_response(self, *args, **kwargs)
        self.send_header('Access-Control-Allow-Origin', '*')

我只是创建了一个继承自SimpleHTTPRequestHandler的新类,该类仅更改了send_response方法。

I had the same problem and came to this solution:

class Handler(SimpleHTTPRequestHandler):
    def send_response(self, *args, **kwargs):
        SimpleHTTPRequestHandler.send_response(self, *args, **kwargs)
        self.send_header('Access-Control-Allow-Origin', '*')

I simply created a new class inheriting from SimpleHTTPRequestHandler that only changes the send_response method.


回答 3

您需要提供自己的do_GET()实例(如果选择支持HEAD操作,则需要提供do_HEAD())。像这样的东西:

class MyHTTPServer(SimpleHTTPServer):

    allowed_hosts = (('127.0.0.1', 80),)

    def do_GET(self):
        if self.client_address not in allowed_hosts:
            self.send_response(401, 'request not allowed')
        else:
            super(MyHTTPServer, self).do_Get()

You’ll need to provide your own instances of do_GET() (and do_HEAD() if choose to support HEAD operations). something like this:

class MyHTTPServer(SimpleHTTPServer):

    allowed_hosts = (('127.0.0.1', 80),)

    def do_GET(self):
        if self.client_address not in allowed_hosts:
            self.send_response(401, 'request not allowed')
        else:
            super(MyHTTPServer, self).do_Get()

如何在Django REST Framework上启用CORS

问题:如何在Django REST Framework上启用CORS

如何在Django REST框架上启用CORS?该参考没有太大帮助,它说我可以通过中间件来完成,但是我该怎么做呢?

How can I enable CORS on my Django REST Framework? the reference doesn’t help much, it says that I can do by a middleware, but how can I do that?


回答 0

您在问题中引用的链接建议使用django-cors-headers,其文档指出要安装该库

pip install django-cors-headers

然后将其添加到已安装的应用程序中:

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

您还需要添加一个中间件类来侦听响应:

MIDDLEWARE_CLASSES = (
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
)

请浏览其文档的配置部分,并特别注意各种CORS_ORIGIN_设置。您需要根据需要设置其中一些。

The link you referenced in your question recommends using django-cors-headers, whose documentation says to install the library

pip install django-cors-headers

and then add it to your installed apps:

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

You will also need to add a middleware class to listen in on responses:

MIDDLEWARE_CLASSES = (
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
)

Please browse the configuration section of its documentation, paying particular attention to the various CORS_ORIGIN_ settings. You’ll need to set some of those based on your needs.


回答 1

pip install django-cors-headers

然后将其添加到已安装的应用程序中:

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

您还需要添加一个中间件类来侦听响应:

MIDDLEWARE_CLASSES = (
    ...
    'corsheaders.middleware.CorsMiddleware',  
    'django.middleware.common.CommonMiddleware',  
    ...
)

CORS_ORIGIN_ALLOW_ALL = True # If this is used then `CORS_ORIGIN_WHITELIST` will not have any effect
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = [
    'http://localhost:3030',
] # If this is used, then not need to use `CORS_ORIGIN_ALLOW_ALL = True`
CORS_ORIGIN_REGEX_WHITELIST = [
    'http://localhost:3030',
]

更多详细信息:https : //github.com/ottoyiu/django-cors-headers/#configuration

阅读官方文档可以解决几乎所有问题

pip install django-cors-headers

and then add it to your installed apps:

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

You will also need to add a middleware class to listen in on responses:

MIDDLEWARE_CLASSES = (
    ...
    'corsheaders.middleware.CorsMiddleware',  
    'django.middleware.common.CommonMiddleware',  
    ...
)

CORS_ORIGIN_ALLOW_ALL = True # If this is used then `CORS_ORIGIN_WHITELIST` will not have any effect
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = [
    'http://localhost:3030',
] # If this is used, then not need to use `CORS_ORIGIN_ALLOW_ALL = True`
CORS_ORIGIN_REGEX_WHITELIST = [
    'http://localhost:3030',
]

more details: https://github.com/ottoyiu/django-cors-headers/#configuration

read the official documentation can resolve almost all problem


回答 2

即使知道最佳选择是使用经过测试的包方法,您也可以使用自定义中间件来进行操作django-cors-headers。这样说,这里是解决方案:

创建以下结构和文件:

myapp/middleware/__init__.py

from corsMiddleware import corsMiddleware

myapp/middleware/corsMiddleware.py

class corsMiddleware(object):
    def process_response(self, req, resp):
        resp["Access-Control-Allow-Origin"] = "*"
        return resp

添加到settings.py标记的行:

MIDDLEWARE_CLASSES = (
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",

    # Now we add here our custom middleware
     'app_name.middleware.corsMiddleware' <---- this line
)

You can do by using a custom middleware, even though knowing that the best option is using the tested approach of the package django-cors-headers. With that said, here is the solution:

create the following structure and files:

myapp/middleware/__init__.py

from corsMiddleware import corsMiddleware

myapp/middleware/corsMiddleware.py

class corsMiddleware(object):
    def process_response(self, req, resp):
        resp["Access-Control-Allow-Origin"] = "*"
        return resp

add to settings.py the marked line:

MIDDLEWARE_CLASSES = (
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",

    # Now we add here our custom middleware
     'app_name.middleware.corsMiddleware' <---- this line
)

回答 3

万一有人回到这个问题并决定编写自己的中间件,这是Django新型中间件的代码示例-

class CORSMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response["Access-Control-Allow-Origin"] = "*"

        return response

In case anyone is getting back to this question and deciding to write their own middleware, this is a code sample for Django’s new style middleware –

class CORSMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response["Access-Control-Allow-Origin"] = "*"

        return response

回答 4

根据文档,对于Django版本> 1.10,可以将自定义MIDDLEWARE编写为函数,例如在文件中:(yourproject/middleware.py作为的同级settings.py):

def open_access_middleware(get_response):
    def middleware(request):
        response = get_response(request)
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Headers"] = "*"
        return response
    return middleware

最后,将此函数的python路径(写入项目的根目录)添加到项目的MIDDLEWARE列表中settings.py

MIDDLEWARE = [
  .
  .
  'django.middleware.clickjacking.XFrameOptionsMiddleware',
  'yourproject.middleware.open_access_middleware'
]

十分简单!

For Django versions > 1.10, according to the documentation, a custom MIDDLEWARE can be written as a function, let’s say in the file: yourproject/middleware.py (as a sibling of settings.py):

def open_access_middleware(get_response):
    def middleware(request):
        response = get_response(request)
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Headers"] = "*"
        return response
    return middleware

and finally, add the python path of this function (w.r.t. the root of your project) to the MIDDLEWARE list in your project’s settings.py:

MIDDLEWARE = [
  .
  .
  'django.middleware.clickjacking.XFrameOptionsMiddleware',
  'yourproject.middleware.open_access_middleware'
]

Easy peasy!


回答 5

好吧,我不认识男人,但是:

在这里使用python 3.6和django 2.2

在settings.py中将MIDDLEWARE_CLASSES重命名为MIDDLEWARE起作用。

Well, I don’t know guys but:

using here python 3.6 and django 2.2

Renaming MIDDLEWARE_CLASSES to MIDDLEWARE in settings.py worked.


回答 6

以下是不需要任何外部模块的工作步骤:

步骤1:在您的应用中创建一个模块。

例如,假设我们有一个名为user_registration_app的应用程序。探索user_registration_app并创建一个新文件。

让我们将其称为custom_cors_middleware.py

粘贴下面的类定义:

class CustomCorsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Headers"] = "*"

        # Code to be executed for each request/response after
        # the view is called.

        return response

步骤2:注册中间件

在您的项目settings.py文件中,添加以下行

‘user_registration_app.custom_cors_middleware.CustomCorsMiddleware’

例如:

  MIDDLEWARE = [
        'user_registration_app.custom_cors_middleware.CustomCorsMiddleware', # ADD THIS LINE BEFORE CommonMiddleware
         ...
        'django.middleware.common.CommonMiddleware',

    ]

请记住,将user_registration_app替换为在其中创建了custom_cors_middleware.py模块的应用程序的名称。

现在,您可以验证它会将必需的响应标头添加到项目中的所有视图中!

Below are the working steps without the need for any external modules:

Step 1: Create a module in your app.

E.g, lets assume we have an app called user_registration_app. Explore user_registration_app and create a new file.

Lets call this as custom_cors_middleware.py

Paste the below Class definition:

class CustomCorsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Headers"] = "*"

        # Code to be executed for each request/response after
        # the view is called.

        return response

Step 2: Register a middleware

In your projects settings.py file, add this line

‘user_registration_app.custom_cors_middleware.CustomCorsMiddleware’

E.g:

  MIDDLEWARE = [
        'user_registration_app.custom_cors_middleware.CustomCorsMiddleware', # ADD THIS LINE BEFORE CommonMiddleware
         ...
        'django.middleware.common.CommonMiddleware',

    ]

Remember to replace user_registration_app with the name of your app where you have created your custom_cors_middleware.py module.

You can now verify it will add the required response headers to all the views in the project!


回答 7

Django = 2.2.12 django-cors-headers = 3.2.1 djangorestframework = 3.11.0

遵循官方指示无效

最后使用旧的方法来解决。

加:

# proj/middlewares.py
from rest_framework.authentication import SessionAuthentication


class CsrfExemptSessionAuthentication(SessionAuthentication):

    def enforce_csrf(self, request):
        return  # To not perform the csrf check previously happening
#proj/settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'proj.middlewares.CsrfExemptSessionAuthentication',
    ),
}

Django=2.2.12 django-cors-headers=3.2.1 djangorestframework=3.11.0

Follow the official instruction doesn’t work

Finally use the old way to figure it out.

ADD:

# proj/middlewares.py
from rest_framework.authentication import SessionAuthentication


class CsrfExemptSessionAuthentication(SessionAuthentication):

    def enforce_csrf(self, request):
        return  # To not perform the csrf check previously happening

#proj/settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'proj.middlewares.CsrfExemptSessionAuthentication',
    ),
}