小白的Django应用

431 阅读7分钟

准备一个接口转发的API

准备Django项目

Django(将够),名字很谦虚,实力可不小。不只是将将够,而是非常够,足够复杂到捏一个生产用的接口应用了。所以用他现有的架构来搭一个接口转发的应用。

本应用的所有代码也是PUA(鼓励)GPT来写的

从建立一个 Django 项目开始,一步步创建一个使用 HTTPS 和 API 密钥认证的 API,我们将分为以下步骤进行:

  1. 创建 Django 项目和应用

    1. 安装 Django:如果你还没有安装 Django,可以使用 pip 来安装它:

      • pip install django
        
    2. 创建一个新的 Django 项目:

      • django-admin startproject myproject
        
    3. 进入项目目录,并创建一个新的 Django 应用:

      • cd myproject
        python manage.py startapp myapp
        
  2. 设置数据库

    1. 默认情况下,Django 使用 SQLite。你可以在 myproject/settings.py 中配置其他数据库(如 PostgreSQL、MySQL),或继续使用 SQLite。

    2. 确保在 settings.py 的 INSTALLED_APPS 中包含 'myapp'

  3. 设计用户和 API 密钥模型

    1. 在 myapp/models.py 中创建一个模型来保存用户和他们的 API 密钥。

      • from django.db import models
        import secrets
        
        class UserAPIKey(models.Model):
            user = models.OneToOneField('auth.User', on_delete=models.CASCADE)
            api_key = models.CharField(max_length=40, default=secrets.token_urlsafe)
        
    2. 运行迁移来更新数据库:

      • python manage.py makemigrations myapp
        python manage.py migrate
        
  4. 创建 API 视图

    1. 在 myapp/views.py 中创建一个 API 视图,使用 Django REST Framework(如果还未安装,请先安装 djangorestframework):

      • pip install djangorestframework
        
    2. 修改 myproject/settings.py,添加 'rest_framework' 到 INSTALLED_APPS

    3. 编写 API 视图和权限类:

      • from django.http import JsonResponse
        from rest_framework.views import APIView
        from rest_framework.permissions import BasePermission
        from .models import UserAPIKey
        
        class APIKeyPermission(BasePermission):
            def has_permission(self, request, view):
                api_key = request.headers.get('Authorization')
                return UserAPIKey.objects.filter(api_key=api_key).exists()
        
        class EchoAPIView(APIView):
            permission_classes = [APIKeyPermission]
        
            def post(self, request):
                # 直接返回接收到的 JSON 数据
                return JsonResponse(request.data)
        
  5. 配置 URL

    1. 在 myapp/urls.py中添加 API 路由:

      • from django.urls import path
        from .views import EchoAPIView
        
        urlpatterns = [
            path('api/echo/', EchoAPIView.as_view(), name='echo_api'),
        ]
        
    2. 在 myproject/urls.py 中包含 myapp 的 URL:

      • from django.urls import path, include
        
        urlpatterns = [
            path('', include('myapp.urls')),
        ]
        
  6. 配置 HTTPS

    1. 对于生产环境,需要获取 SSL/TLS 证书并在 Web 服务器(如 Nginx 或 Apache)上配置。

    2. 对于开发环境,可以使用 django-sslserver

      • pip install django-sslserver
        
      •     在 settings.py 中添加 'sslserver' 到 INSTALLED_APPS,然后使用:

      • python manage.py runsslserver
        

通过这些步骤,你就可以设置一个具有 API 密钥认证的 HTTPS Django API。这个 API 接收JSON输入,并将其原样输出。

  1. 自己签名

签名是一种认证机制,自己签名就相当于董事长自己给自己办了个门卡,公司内外出入无阻。

正儿八经的公司里面,董事长是不会自己去办卡的。所以正儿八经的应用里面,签名和认证都是需要更为规范的体系来做的。

本人测试就是个草台班子,所以这个案例里面的董事长也就只能自己办出入的门卡了。

openssl是一个简单的生成测试用的个人证书的工具,关键是免费。

A. 使用正确的 SSL 证书文件:

  • 检查您的证书文件。您需要一个由您的 CSR 请求生成的证书文件(通常为 .crt 或 .pem)。如果您只有 CSR,您需要完成证书的签发过程,或使用自签名证书生成 .crt 文件。
  • 如果您要生成一个自签名证书,可以使用 OpenSSL 命令行工具:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout mykey.pem -out mycert.pem
  • 这将生成一个有效期为 365 天的自签名证书 mycert.pem 和一个私钥 mykey.pem

B. 更新 Django SSL Server 命令:

  • 确保您在启动 Django SSL Server 时使用正确的证书和密钥文件。例如:
python manage.py runsslserver --certificate /path/to/certs/mycert.pem --key /path/to/certs/mykey.pem 0.0.0.0:8000

里面的地址要换成你自己的路径。

  1. 生成密钥

密钥不是蜜月,但是跟蜜月一样,都只有非常短的保质期

在另一个terminal里面

在测试 API 时,您需要将 api-key 替换为在数据库中为特定用户生成的有效 API 密钥。这里是详细的步骤来生成和使用 API 密钥:

生成 API 密钥:

  • 在 Django 管理界面中创建用户和相应的 API 密钥,或者通过 Django shell 手动添加。
  • 例如,使用 Django shell 生成并保存 API 密钥:
python manage.py shell
  • 然后在 shell 中:
from django.contrib.auth.models import User
from myapp.models import UserAPIKey
import secrets

# 创建或选择一个用户
user, created = User.objects.get_or_create(username='your_username', defaults={'password': 'your_password'})
# 生成 API 密钥
api_key, key_created = UserAPIKey.objects.get_or_create(user=user, defaults={'api_key': secrets.token_urlsafe()})
print(api_key.api_key)  # 这将显示生成的 API 密钥
  • 记录下显示的 API 密钥,这将用于 API 调用。

本地测试接口转发的功能

将authorization里面的key换成你自己的

curl -k -X POST https://localhost:8000/api/echo/ \
    -H "Content-Type: application/json" \
    -H "Authorization: craze-V50-key" \
    -d '{"key1":"value1","key2":"value2"}'

这里做了一个简单的json数组验证{"key1":"value1","key2":"value2"}。

将这个Django项目放在云上

不要199,只要99,甚至不要钱(如果你是新用户,可以0元购,申请试用),阿里云白嫖带回家(这里不是广告)。

本地跑通的Django项目,放在你建好的阿里云ECS实例上,并且在项目中,把服务器的ip地址加进去就可以。

Django项目的配置 ( settings.py 文件):

  1. ALLOWED_HOSTS:

    1. 确保你的 ALLOWED_HOSTS 设置包括你的域名和子域名。例如:
    2. ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']
      
  2. SECURE_PROXY_SSL_HEADER:

    1. 如果你使用Nginx作为反向代理,并且你的Django应用运行在非标准端口上,设置 SECURE_PROXY_SSL_HEADER 来信任Nginx传递的 X-Forwarded-Proto 头部:
    2. SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
      
  3. USE_X_FORWARDED_HOST:

    1. 如果Nginx设置了一个不同的服务器名称或端口,你可能需要设置 USE_X_FORWARDED_HOST 来解析正确的主机名:
    2. USE_X_FORWARDED_HOST = True
      
  4. CSRF_COOKIE_SECURE 和 SESSION_COOKIE_SECURE:

    1. 确保CSRF令牌和会话Cookie只在HTTPS连接中发送:
    2. CSRF_COOKIE_SECURE = True
      SESSION_COOKIE_SECURE = True
      
  5. SECURE_SSL_REDIRECT:

    1. 如果你想要所有的HTTP请求都重定向到HTTPS,可以设置:
    2. SECURE_SSL_REDIRECT = True
      
  6. SECURE_BROWSER_XSS_FILTER 和 SECURE_CONTENT_TYPE_NOSNIFF:

    1. 启用额外的安全设置:
    2. 复制
      SECURE_BROWSER_XSS_FILTER = True
      SECURE_CONTENT_TYPE_NOSNIFF = True
      

将服务发布到公域上

启动Gunicorn

Gunicorn是一个Python WSGI HTTP服务器,用于Unix系统。它是预叉的,也就是说,它在工作进程启动时创建一个worker进程,并且每个worker进程都是独立的。Gunicorn旨在快速执行和低内存使用,因此它是一个非常适合运行Python网络应用的服务器。

在Django项目中,Gunicorn通常用作应用服务器,与Nginx或Apache等反向代理服务器一起使用,以提供更健壮和高效的生产环境部署。

Gunicorn的作用:

  1. 性能:Gunicorn提供了一个预加载的应用环境,这意味着你的Django应用只需要加载一次,从而提高了性能。
  2. 多进程:Gunicorn可以利用多个CPU核心,通过并行运行多个工作进程来提供并发服务。
  3. 易于使用:Gunicorn的安装和配置非常简单,它提供了命令行工具来启动和管理服务器。
  4. 稳定性:作为一个成熟的服务器,Gunicorn能够稳定地运行Django应用。

配置nginx

为了使Nginx能够将请求转发给Gunicorn,你需要确保Nginx配置中的server块中的location部分正确设置了proxy_pass指令。

通常这个文件位于 /etc/nginx/nginx.conf 或者 /etc/nginx/sites-available/default(取决于你的操作系统和 Nginx 的安装方式)。以下是配置 HTTPS 转发的基本步骤:

以下是一个基本的Nginx配置示例,它将所有HTTP请求转发给运行在8000端口上的Gunicorn:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /path/to/your/fullchain.pem;
    ssl_certificate_key /path/to/your/privkey.pem;

    # SSL settings (customize as needed)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:...';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
}

其中域名,证书文件的地址,这两个要换成你自己的。签名的算法,也要和你生成证书用的一致即可。

请按照以下步骤操作:

  1. 替换域名或IP: 将your_domain_or_IP替换为你的服务器的域名或公网IP地址。
  2. 测试Nginx配置: 在应用更改之前,使用以下命令测试Nginx配置文件的语法:
sudo nginx -t

重新加载或重启Nginx: 如果测试成功,重新加载Nginx配置或重启Nginx服务:

sudo nginx -s reload

确保Gunicorn运行: 确认Gunicorn正在运行,并且监听的端口和IP地址与Nginx配置中指定的proxy_pass指令相匹配。

image.png