Я получаю ответ 403 от сервера в моем новом приложении Django. Это очень просто. У меня даже нет моделей, я просто хочу вернуть аудиофайл, но хочу сделать это через API. Из-за этого, поскольку у меня не будет пользователей, мне нужен ключ API, и я обнаружил, что могу использовать платформу Django REST и ключевые модули API платформы REST. Я следил за краткими инструкциями и, похоже, не получил ответа. Раньше он работал, но аутентифицировался через CSRF, и, как я уже сказал, это будет API, поэтому у меня не будет файлов cookie CSRF.
Вот представление, которое я использую:
@api_view(["POST"])
def tts_view(request):
data = request.POST
voice_name = data.get("voice_name")
text = data.get("text")
if not voice_name or not text:
return JsonResponse({"error": "Missing voice_name or text"}, status=400)
return JsonResponse({"wav": text_to_wav(voice_name, text)}, status=200, safe=False)
Настройки:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_api_key',
'TTS',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'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',
]
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework_api_key.permissions.HasAPIKey",
]
}
И выборка (ключ API — это просто тест, так что это не имеет значения):
fetch('/create-speech', {
method: 'POST',
body: JSON.stringify({
voice_name: "es-US-Neural2-B",
text: "Estoy feliz"
}),
headers: {
'Authorization': '0tSMNivu.f8DOBrHTTKfMQBGANNbjl5BJQcswN9ay',
'Content-Type': 'application/json'
}
})
.then((resp) => {
if (!resp.ok) throw Error(`${resp.statusText} - ${resp.status}`);
return resp.json();
})
.then((wav) => {
console.info('success');
});
Я делаю выборку в консоли на странице по умолчанию, которая не определена (как я уже сказал, мне нужен только API).
Я пытался включить rest_framework.permissions.AllowAny в DEFAULT_PERMISSION_CLASSES, но это тоже не работает.
Я действительно не знаю, что еще делать, поэтому любая помощь будет оценена по достоинству. Спасибо!






Вы должны добавить класс разрешения исключения CSRF или декоратор, например:
from django.views.decorators.csrf import csrf_exempt
и над объявлением представления API:
@api_view(["POST"])
@csrf_exempt
def tts_view(request):
При этом убедитесь, что вы передаете свой токен API DRF в заголовках в вызове API как
Authorization: Token token_string
должно хватить.
Из документации Django REST Framework API Key:
По умолчанию клиенты должны передавать свой ключ API через заголовок авторизации. Он должен быть отформатирован следующим образом:
Authorization: Api-Key <API_KEY>
Вам не хватает части Api-Key (обратите внимание на пробел между ней и частью <API_KEY>). Таким образом, ваш запрос должен быть:
fetch('/create-speech', {
...
headers: {
'Authorization': 'Api-Key 0tSMNivu.f8DOBrHTTKfMQBGANNbjl5BJQcswN9ay',
'Content-Type': 'application/json'
}
})
...
Ты прав! Мне этого не хватало. Но все равно не работает :(
Все еще 403? Какие-нибудь подробности в теле ответа?
Все еще 403, но я успел рассмотреть детали. Он говорит {\"detail\":\"CSRF Failed: CSRF token missing.\"} при печати функции ответов .text(). Я пытался использовать декоратор csrf_exempt, но он не работает @Igonato
Я только что проверил, и я получаю тот же результат, если не включать Api-Key в заголовок Authorization, так что это должно быть какая-то ошибка rest_framework_api_key
Это что-то с сетью! Я скачал Postman и все заработало. Теперь мне нужно выяснить, что делать в Интернете
Если вы не используете аутентификацию на основе файлов cookie, безопасно полностью отключить защиту csrf. Странно, что декоратор не работал...
Размещение может иметь значение. Поменяйте его на api_view, посмотрите, поможет ли это.
Подождите, я получил его на работу! Я удалил файлы cookie, сеанс и csrftoken, и это просто сработало. Я думаю, именно поэтому это сработало на Postman — у него не было csrftoken. Спасибо!
Он все еще не работает, но спасибо!