You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何保护Django公开端点仅允许React应用访问?

保护Django /helloKitty端点的实用方案

要保护你的Django /helloKitty 端点,只允许你的React应用访问,这里提供几种实用的实现方案,根据你的部署场景选择即可:

方案1:验证请求来源(适合同域/固定可信域名场景)

如果你的React应用和Django后端同域部署,或者前端域名是固定且可信的,可以通过检查请求的Origin或Referer头来拦截非法访问。

修改views.py中的helloKitty函数:

from django.http import HttpResponseForbidden, HttpResponse
import pandas as pd

def helloKitty(request):
    # 替换为你的React应用实际域名,生产环境注意使用HTTPS
    allowed_origins = ['http://localhost:3000', 'https://your-production-react-domain.com']
    
    origin = request.headers.get('Origin')
    referer = request.headers.get('Referer')
    
    # 验证请求来源是否在允许列表内
    valid_source = False
    if origin in allowed_origins:
        valid_source = True
    elif referer:
        # 检查Referer是否包含允许的域名
        valid_source = any(domain in referer for domain in allowed_origins)
    
    if not valid_source:
        return HttpResponseForbidden("无访问权限")
    
    hello = pd.read_csv('static/data/helloKitty_data.csv')
    hello = hello.to_json(orient='records')
    return HttpResponse(hello)

方案2:API密钥验证(适合跨域/独立部署场景)

给前端分配唯一API密钥,请求时在请求头中携带,后端验证密钥有效性。

后端修改(views.py)

from django.http import HttpResponseForbidden, HttpResponse
import pandas as pd
import os

def helloKitty(request):
    # 建议从环境变量读取密钥,避免硬编码泄露
    VALID_API_KEY = os.environ.get('KITTY_API_KEY', 'your-default-secret-key')
    
    api_key = request.headers.get('X-API-Key')
    if api_key != VALID_API_KEY:
        return HttpResponseForbidden("无效的API密钥")
    
    hello = pd.read_csv('static/data/helloKitty_data.csv')
    hello = hello.to_json(orient='records')
    return HttpResponse(hello)

前端修改(React zustand store)

在axios请求中添加X-API-Key头,注意生产环境用环境变量注入密钥:

import React from "react";
import { create } from 'zustand';
import axios from 'axios';

const kittyStore = create((set) => ({
    kitten: [],

    fetchKitty: async () => {
        const response = await axios.get('/helloKitty', {
            headers: {
                // 开发环境可直接写,生产环境用process.env.REACT_APP_KITTY_API_KEY
                'X-API-Key': process.env.REACT_APP_KITTY_API_KEY || 'your-default-secret-key'
            }
        });
        const hello = response.data.map((h) => ({
            name: h.name,
            age: h.age,
        }));
        set({ kitten: hello })
    },
}));

export default kittyStore;

提示:React项目中,环境变量需要以REACT_APP_开头,放在.env文件中,部署时由服务器注入。

方案3:JWT认证(需用户登录的场景)

如果你的应用需要用户登录后才能访问数据,使用JWT令牌进行身份验证是更安全的选择。

1. 安装依赖

pip install djangorestframework-simplejwt

2. 配置Django settings.py

INSTALLED_APPS = [
    # 已有应用
    'rest_framework',
    'rest_framework_simplejwt',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

3. 添加JWT路由到urls.py

from django.urls import path 
from . import views 
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView

app_name = 'Main'
urlpatterns = [
    path("helloKitty/", views.helloKitty, name='helloKitty'),
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

4. 修改视图函数启用JWT验证

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
import pandas as pd

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def helloKitty(request):
    hello = pd.read_csv('static/data/helloKitty_data.csv')
    return Response(hello.to_json(orient='records'))

前端修改(获取并携带JWT令牌)

// 先实现登录获取令牌(示例)
const login = async (username, password) => {
    const res = await axios.post('/api/token/', { username, password });
    localStorage.setItem('access_token', res.data.access);
};

// 请求数据时携带令牌
const kittyStore = create((set) => ({
    kitten: [],

    fetchKitty: async () => {
        const token = localStorage.getItem('access_token');
        const response = await axios.get('/helloKitty', {
            headers: {
                'Authorization': `Bearer ${token}`
            }
        });
        const hello = response.data.map((h) => ({
            name: h.name,
            age: h.age,
        }));
        set({ kitten: hello })
    },
}));

内容的提问来源于stack exchange,提问作者x945

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 00:02:10