如何防止Django将管理URI重写为/admin而不是/api/admin/

如何防止Django将管理URI重写为/admin而不是/api/admin/,django,docker,kubernetes,django-admin,nginx-ingress,Django,Docker,Kubernetes,Django Admin,Nginx Ingress,正在将Django API放入Kubernetes 发送到/入口nginx控制器的任何流量都会发送到React FE。发送到/api的任何流量都将发送到Django BE 这是ingress serivce.yaml的相关部分: apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-service annotations: kubernetes.io/ingress.class: nginx

正在将Django API放入Kubernetes

发送到
/
入口nginx控制器的任何流量都会发送到React FE。发送到
/api
的任何流量都将发送到Django BE

这是ingress serivce.yaml的相关部分:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - http:
        paths:
          - path: /?(.*)
            backend:
              serviceName: client-cluster-ip-service
              servicePort: 3000
          - path: /api/?(.*)
            backend:
              serviceName: server-cluster-ip-service
              servicePort: 5000
这是
url.py

FORCE_SCRIPT_NAME = '/api/'
从django.contrib导入管理 从django.url导入包括,路径

urlpatterns = [
    path('auth/', include('authentication.urls'), name='auth'),
    path('admin/', admin.site.urls, name='admin'),
]
客户端
部分工作正常。
minikube
IP是
192.168.99.105
。导航到该IP将加载react前端

导航到
192.168.99.105/api/auth/test/
会给我带来一个“Hello World!”的回复,我很快做出了回应

但是,当我尝试转到
192.168.99.105/api/admin
时。它会自动将我重定向到
/admin/login/?next=/admin/
,如果
/api
被删除,则该位置不存在是否有任何方法可以防止这种行为?

我也试过这个:

入口服务。yaml

- http:
    paths:
      - path: /?(.*)
        backend:
          serviceName: client-cluster-ip-service
          servicePort: 3000
      - path: /api/?(.*)
        backend:
          serviceName: server-cluster-ip-service
          servicePort: 5000
      - path: /admin/?(.*)
        backend:
          serviceName: server-cluster-ip-service
          servicePort: 5000
url.py

urlpatterns = [
    path('auth/', include('authentication.urls'), name='auth'),
    path('/', admin.site.urls),
]
这只会产生“未找到”

我还尝试使用以下模式作为前缀:

但这只是使它成为
/api/api

以下是在
站点包/django/contrib/admin/sites
中为
admin/
定义的路由:

# Admin-site-wide views.
urlpatterns = [
    path('', wrap(self.index), name='index'),
    path('login/', self.login, name='login'),
    path('logout/', wrap(self.logout), name='logout'),
    path('password_change/', wrap(self.password_change, cacheable=True), name='password_change'),
    path(
        'password_change/done/',
        wrap(self.password_change_done, cacheable=True),
        name='password_change_done',
    ),
    path('jsi18n/', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
    path(
        'r/<int:content_type_id>/<path:object_id>/',
        wrap(contenttype_views.shortcut),
        name='view_on_site',
    ),
]
#管理站点范围的视图。
URL模式=[
路径(“”,wrap(self.index),name='index'),
路径('login/',self.login,name='login'),
路径('logout/',wrap(self.logout),name='logout'),
路径('password\u change/',wrap(self.password\u change,cacheable=True),name='password\u change'),
路径(
“密码更改/完成/”,
包装(self.password\u change\u done,cacheable=True),
name='password\u change\u done',
),
path('jsi18n/',wrap(self.i18n_javascript,cacheable=True),name='jsi18n'),
路径(
“r///”,
换行(contenttype_views.shortcut),
name='view''u on_site',
),
]

我猜是
'
导致Django将
/api
从URL中删除,并将其改为
192.168.99.105/admin
,而不是
192.168.99.105/api/admin
好的,最后找到了答案。绝对是一个Django背景。将以下内容添加到Django
settings.py

FORCE_SCRIPT_NAME = '/api/'
然后我必须更新
静态URL
,因为它不再为管理员门户提供资产:

STATIC_URL = '/api/static/`
我正在使用的完整
settings.py
,但实际上唯一需要更改的是添加
FORCE\u SCRIPT\u NAME
和更新
STATIC\u URL

Django settings for config project.

Generated by 'django-admin startproject' using Django 2.2.6.

For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""

import os
from datetime import timedelta

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Forces Django to not strip '/api' from the URI
FORCE_SCRIPT_NAME = '/api/'

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ['SECRET_KEY']

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ['DEBUG'] == 'True'

ALLOWED_HOSTS = [
        'localhost',
        '127.0.0.1',
        '192.168.64.7'
]


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Third-party packages
    'rest_framework',

    # Local packages
    'authentication'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'config.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'config.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ['PGDATABASE'],
        'USER': os.environ['PGUSER'],
        'PASSWORD': os.environ['PGPASSWORD'],
        'HOST': os.environ['PGHOST'],
        'PORT': 1423
    }
}

# REST Framework settings
# https://www.django-rest-framework.org/
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ],
}

# SIMPLE_JWT Settings
# https://github.com/davesque/django-rest-framework-simplejwt
SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': True,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': os.environ['SECRET_KEY'],
    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,

    'AUTH_HEADER_TYPES': ('Bearer',),
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',

    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',

    'JTI_CLAIM': 'jti',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'America/Los_Angeles'
USE_I18N = True
USE_L10N = True
USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/api/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

Dockerfile

FROM python:3.7-slim
ENV PYTHONUNBUFFERED 1
WORKDIR /app
EXPOSE 5000
COPY requirements*.txt ./
RUN pip install -r requirements.txt
COPY . .
RUN python manage.py collectstatic
CMD ["gunicorn", "-b", ":5000", "--log-level", "info", "config.wsgi:application"]

最佳做法是在django url模式前面加上
/api
,大多数帖子都是2014年发布的。可能相关的那个对我不起作用()。只需使
/auth/test
/admin
返回
“未找到”
。检查
入口服务.yaml
。BE的任何流量都已通过前缀为
/api
。因此,如果它的前缀是
url.py
path('api/auth'..
),那么您必须导航到
/api/api/auth/test/
,才能获得响应。不确定处理此问题的最佳方法,但我不认为删除
/api/?(*)
确实是一个选项,因为它需要公开。我同意你不应该更改入口文件,我们只需要找出如何为url添加前缀。很抱歉,链接误导了你。你使用哪个django版本?让我们看看如何添加url模式prefix@EfratLevitan不用担心,我很感谢你的帮助!我正在使用2.2。我已经更新了m我尝试了一个前缀模式的y问题,结果只是执行了
/api/api/
。我还使用了完整的
入口服务进行了更新。yaml
,以防其他原因造成。您可以共享您的最新配置吗?您是否保留了问题中的所有配置,并将这两行添加到settings.py file?如果你能帮助我,我将不胜感激。谢谢@ğatayBarın是的,实际上只有这两种设置。我已经添加了完整的
设置。py
如果有帮助的话。React和Django现在合作得很好。我唯一的问题是我不能为Django提供静态文件。你有单独的PVC用于静态文件吗?你的条件如何配置?我尝试了静态根目录或静态URL的不同组合,已经筋疲力尽了。如果您能帮助我,我将不胜感激。谢谢。在Django方面,我仅有的静态文件是用于管理门户的。我正在使用
gunicorn
和。在我的
Dockerfile
中,我有它
python manage.py collectstatic
。我发布了我的
Dockerfile
,其中包含
gunicorn
collectstatic
内容。
whitenoise
设置在
settings.py
中。