首页 > 解决方案 > 错误:请求失败,在 axios post api 中出现代码 403

问题描述

我在这个问题上挣扎了一段时间。我有一个新的 django-vue 项目,刚刚创建了它。当我按下一个发出 api 请求的按钮时,我收到 403 错误并通过控制台收到“Forbidden (CSRF cookie not set.):”。我做了一些其他的小新手项目,我之前从未在 api 帖子中传递过 CSRF 令牌。我认为那一定是另一个错误,但我不知道是哪个错误

代码如下:

视图.py

from django.shortcuts import render
from django.http import HttpRequest, HttpResponse, JsonResponse, HttpResponseRedirect
from django.shortcuts import redirect
from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required


import requests


def discord_login(request):
    print('Hola, cómo estas')
    return redirect(auth_url_discord)

设置.py


from pathlib import Path


ALLOWED_HOSTS = []


# Application definition

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

    'rest_framework',
    'rest_framework.authtoken', 
    'corsheaders', 
    'djoser',

    'key',
    'discordlogin',
]

CORS_ALLOWED_ORIGINS = [
    'http://localhost:8080',
]



REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
}

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

ROOT_URLCONF = 'leviathan_django.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 = 'leviathan_django.wsgi.application'




DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}



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',
    },
]



LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True



STATIC_URL = '/static/'



DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

家.vue

<template>
  <div class="home">
    <div>
    
      <button class="button is-dark" v-on:click="loginWDiscord()">Login with discord</button>

    </div>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'Home',

  mounted() {
    document.title = 'Home | Leviathan'
  },
  methods: {
    
      async loginWDiscord() {


      await axios 
          .post("http://127.0.0.1:8000/api/v1/oauth2/login/")
          .then(response => {
              console.log(response)              
          })
          .catch(error => {
              console.log(error)
          })

      }

    },
}
</script>

编辑:我刚刚在我的视图代码之前添加了 api_view @api_view(['POST']),现在错误是:“对预检请求的响应没有通过访问控制检查:没有 'Access-Control-Allow-Origin' 标头是出现在请求的资源上。” 恶心:_(

标签: djangoapivue.jsdjango-rest-frameworkaxios

解决方案


您可以通过这种方式在您的 axios 调用中添加 CSRF TOKEN:

假设您将令牌的值存储在一个名为 的变量中csrfToken

methods: {

  async loginWDiscord() {
  // Get the csrf-token
  csrfToken = "{% csrf_token %}";
  post_url = 'http://127.0.0.1:8000/api/v1/oauth2/login/';

  await axios(
      {
          method: 'post',
          url: post_url,
          data: {  // Change the datas to post for suit your needs
              username: 'demo',
              password: 'MyG00dyP4ss'
          },
          headers: {"X-CSRFToken": csrfToken},  // Here you pass the token
      })
      .then(response => {
          console.log(response)              
      })
      .catch(error => {
          console.log(error)
      })

  }

},

推荐阅读