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

如何配置Docker部署的Django后端,使其仅接受来自已认证前端的请求?

嘿,这个问题我太熟了!你现在的核心痛点是CORS只是浏览器的同源策略限制,根本不是服务器端的访问控制——所以即使开了CORS,任何人直接用curl、Postman甚至浏览器地址栏敲API地址,还是能拿到响应。要解决这个,用JWT做身份校验绝对是正确的方向,而且你已经用了Auth0,正好可以无缝衔接,下面一步步给你捋清楚:

核心方案:基于Auth0 JWT的后端认证校验

因为前端已经集成了Auth0,后端只需要做两件事:验证前端传来的Auth0签发的JWT令牌,以及要求所有API接口必须通过认证才能访问。

1. 让后端能验证Auth0的JWT

Auth0用的是RS256非对称加密算法签发JWT,所以后端需要用Auth0的公钥来验证令牌的合法性,而不是自己存密钥。

步骤1:安装依赖

先装两个必要的包:

pip install pyjwt cryptography

pyjwt用来解析和验证JWT,cryptography处理加密相关的操作。

步骤2:自定义DRF认证类

在你的Django app里新建一个authentication.py,写一个专门处理Auth0 JWT的认证类:

import jwt
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from django.conf import settings

class Auth0JWTAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 从请求头里拿Authorization令牌
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            # 没有令牌的话,返回None,后续权限校验会拦截请求
            return None

        token = auth_header.split(' ')[1]
        try:
            # 从Auth0的JWKS端点获取公钥(建议缓存公钥,避免每次请求都拉取)
            jwks_client = jwt.PyJWKClient(settings.AUTH0_JWKS_URL)
            signing_key = jwks_client.get_signing_key_from_jwt(token).key

            # 验证令牌的合法性,包括签名、过期时间、受众、签发者
            payload = jwt.decode(
                token,
                signing_key,
                algorithms=['RS256'],
                audience=settings.AUTH0_API_AUDIENCE,
                issuer=settings.AUTH0_ISSUER
            )

            # 这里可以根据payload里的用户信息(比如sub字段,是Auth0用户的唯一ID)
            # 在你的数据库中创建或查找对应用户,方便后续权限控制
            # 示例:user, created = User.objects.get_or_create(username=payload['sub'])

            # 返回(用户对象, 令牌),DRF会标记该请求为已认证
            return (payload, token)
        except jwt.ExpiredSignatureError:
            raise AuthenticationFailed('令牌已过期,请重新登录')
        except jwt.InvalidTokenError:
            raise AuthenticationFailed('无效的认证令牌')

步骤3:配置Django和DRF

在settings.py里添加Auth0相关配置和DRF的认证权限设置:

# Auth0配置
AUTH0_DOMAIN = '你的Auth0域名(比如xxx.auth0.com)'
AUTH0_API_AUDIENCE = '你的Auth0 API标识符(在Auth0控制台里创建的API的Audience)'
AUTH0_ISSUER = f'https://{AUTH0_DOMAIN}/'
AUTH0_JWKS_URL = f'https://{AUTH0_DOMAIN}/.well-known/jwks.json'

# DRF配置
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        '你的app名称.authentication.Auth0JWTAuthentication',
    ],
    # 全局设置所有API默认需要认证,个别不需要的视图可以单独覆盖
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}

2. 前端如何把JWT传递给后端

前端已经用Auth0登录了,Auth0的SDK会帮你管理令牌(主要是access_token),你只需要在每次调用后端API时,把令牌放到请求头里。

React里的实现示例(用Auth0 SDK和Axios)

import { useAuth0 } from '@auth0/auth0-react';
import axios from 'axios';

// 创建一个Axios实例,统一处理API请求
const apiClient = axios.create({
  baseURL: 'http://你的后端API地址/api/',
});

// 添加请求拦截器,自动带上Authorization头
apiClient.interceptors.request.use(async (config) => {
  const { getAccessTokenSilently } = useAuth0();
  try {
    // 从Auth0获取有效的access_token
    const token = await getAccessTokenSilently({
      audience: '你的Auth0 API标识符(和后端配置的一致)',
    });
    config.headers.Authorization = `Bearer ${token}`;
    return config;
  } catch (error) {
    // 获取令牌失败,比如用户未登录,这里可以跳转到登录页
    throw error;
  }
});

// 然后用这个apiClient调用后端接口,比如:
// const response = await apiClient.get('/your-endpoint/');
export default apiClient;

3. 额外的安全加固

  • 严格配置CORS:不要用CORS_ALLOW_ALL_ORIGINS = True,只允许你的前端域名:
    CORS_ALLOWED_ORIGINS = [
        "http://你的前端域名:3000",
        # 生产环境的域名也要加上
    ]
    
  • 处理令牌过期:Auth0的access_token默认1小时过期,前端要通过Auth0的SDK自动刷新令牌(上面的getAccessTokenSilently已经会自动处理刷新)。
  • 不要暴露敏感信息:前端不要把令牌存在localStorage(容易被XSS攻击),Auth0的SDK默认会把令牌存在HttpOnly的Cookie里,更安全。
  • 限制API的HTTP方法:比如只允许POST/PUT/DELETE请求携带令牌,GET请求也建议做认证(除非是完全公开的接口)。

效果验证

配置完成后,直接在浏览器地址栏访问my-site/api/,会返回401 Unauthorized;只有前端登录后,通过带令牌的请求才能正常获取API响应。


内容的提问来源于stack exchange,提问作者K.I.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:57:29