При разбивке DRF на страницы “следующая” ссылка использует устаревшее имя хоста при входе в GKE — как мне заставить его использовать реальный хост?
Каковы детали вашей проблемы?
Я запускаю API фреймворка Django REST на движке Google Kubernetes (GKE) за входом. Когда я запрашиваю:
https://www.my-api-url.com/api/stores/?page=1&active=true
Я получаю правильные результаты, но разбивка на страницы следующая ссылка создается с использованием устаревшего имени хоста :
https://api-back.my-api-url.com/api/stores/?active=true&page=2
Это имя хоста использовалось в предыдущем ingress, но было удалено. Я просмотрел всю кодовую базу, манифесты Kubernetes и конфигурации ingress и нигде не смог его найти. Я нашел этот связанный с этим вопрос, в котором говорится, что DRF использует имя хоста запроса для пагинатора, но я все еще не могу понять откуда берется этот устаревший хост в настройках GKE /Ingress: Как изменить хост в следующем ключе в разбитом на страницы URL-адресе в django rest framework?
Что вы пробовали и чего ожидали?
Я ожидал, что DRF построит next с помощью www.my-api-url.com. Я проверил и/или попробовал:
ALLOWED_HOSTSсодержит правильный хост.Переключение
USE_X_FORWARDED_HOST(Истина/ложь).Установка
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https').Убедитесь, что для нового входа используется правильный общедоступный хост, и полностью удалите старый.
Проверено отсутствие жестко запрограммированных ссылок на
api-back.my-api-url.comв манифестах репозитория или K8s.Несмотря на это, в ссылке
nextпо-прежнему отображается устаревшее имя хоста.Вопрос: При настройке входа в GKE, какой заголовок/ параметр фактически управляет хостом, используемым для разбивки на страницы DRF, и как я могу гарантировать, что
nextиспользует реальное общедоступное имя хоста? Если это происходит из перенаправленного заголовка, какой конкретный входной заголовок / конфигурацию я должен установить (или отменить)?
DRF builds pagination links using request.build_absolute_uri(), which depends on the Host header it receives.
If your app is behind a GKE Ingress or Load Balancer, it’s likely not forwarding the original host —
so Django sees your internal service name like api-back.my-api-url.com.
1. In your Django settings.py:
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
2.In your Ingress annotations, preserve the original host:
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
3.If needed, override DRF’s pagination link generator:
from rest_framework.pagination import PageNumberPagination
class FixedHostPagination(PageNumberPagination):
def get_next_link(self):
url = super().get_next_link()
if url:
return url.replace('api-back.my-api-url.com', 'www.my-api-url.com')
return None
Why it happens:
Your ingress or proxy rewrites the Host header to the internal service name.
DRF uses that to build links, so you end up with stale internal URLs.