带有Axios的ReactJS和Django-CSRF令牌和带有POST请求的表单数据

时间:2019-03-23 08:10:32

标签: django reactjs axios csrf django-allauth

我已经阅读了多个示例并尝试了所有代码-出于某些奇怪的原因,这些都无法与我当前的项目一起使用。

如果我使用邮递员,则可以毫无问题地添加用户。

当我尝试在React中复制邮递员请求时,它的处理过程相同,但没有用户详细信息保存到Django数据库中。

我已经尝试了Django休息,研究并阅读了两天的线程。

Django设置

"""
Django settings for demo_project project.

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

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

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

import os

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


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

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '58u29^u@wy%90)%ni=u5muf1h(g@*el*o$q%nvnxji3*yg!1hl'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['localhost']


# Application definition

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

    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.google',


    'users',
    'pages',
]

# custom user model
AUTH_USER_MODEL = 'users.CustomUser'

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

ROOT_URLCONF = 'demo_project.urls'

# redirect urls for auth
LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'

# custom authentication backends
AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend",
)

SITE_ID = 1

ACCOUNT_EMAIL_REQUIRED = True  # we want to store their email in django
ACCOUNT_USERNAME_REQUIRED = False  # we're not worried about user names

# CORS config
# CORS_ORIGIN_WHITELIST = (
#     'localhost:5000',
#     '127.0.0.1:5000'
#     'localhost:3000',
#     '127.0.0.1:3000'
# )

# CORS_ORIGIN_ALLOW_ALL = True

# CORS_ALLOW_CREDENTIALS = True
# CORS_ALLOW_HEADERS = (
#     'xsrfheadername',
#     'xsrfcookiename',
#     'content-type',
#     "X-CSRFTOKEN"
# )

#CSRF_COOKIE_NAME = "XSRF-TOKEN"
CSRF_COOKIE_NAME = "csrftoken"


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        '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 = 'demo_project.wsgi.application'


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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.1/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.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/

STATIC_URL = '/static/'

反应前端表单

import React, { Component } from "react";
import axios from "axios";
import "./App.css";
import cookie from "react-cookies";
axios.defaults.xsrfHeaderName = "X-CSRFToken";
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.withCredentials = true;

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      email: "hihi@gmail.com",
      password1: "test123T",
      password2: "test123T"
    };
  }

  handleChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };

  handleSubmit = e => {
    e.preventDefault();
    var myUrl = "/accounts/signup/";
    var myData = "email=hihi%40gmail.com&password1=test123T&password2=test123T";
    axios
      .post(myUrl, myData, {
        headers: {
          "X-CSRFToken": cookie.load("csrftoken"),
          "Content-Type": "application/x-www-form-urlencoded",
          "cache-control": "no-cache"
        }
        // other configuration there
      })
      .then(function(response) {
        alert("yeah!");
        console.log(response);
      })
      .catch(function(error) {
        alert("oops");
        console.log(error);
      });
  };

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <h3>This is going to be a register form hopefully</h3>
          <form onSubmit={this.handleSubmit}>
            {/* {% csrf_token %} */}
            {/* {{ form.as_p }} */}

            <input
              placeholder="email"
              onChange={this.handleChange}
              type="email"
              name="email"
            />
            <input
              placeholder="pw1"
              onChange={this.handleChange}
              type="password"
              name="password1"
            />
            <input
              placeholder="pw2"
              onChange={this.handleChange}
              type="password"
              name="password2"
            />

            <button type="submit">Sign up</button>
          </form>
        </header>
      </div>
    );
  }
}

export default App;

包json中的代理

  "proxy": "http://localhost:8000"

我的请求标头和表单数据无后顾之忧

请求标头

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
cache-control: no-cache
Connection: keep-alive
Content-Length: 60
Content-Type: application/x-www-form-urlencoded
Cookie: csrftoken=pw59YcUID3RjZOOmcJlIUGNv1sBZQlRvX1hcNOkNVzMOEl0ETRUeZkTCU0lnVO1s; sessionid=17j037bo4oju0v6jprpkuv6x26m0eajt
Host: localhost:3000
Origin: http://localhost:3000
Referer: http://localhost:3000/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
X-CSRFToken: pw59YcUID3RjZOOmcJlIUGNv1sBZQlRvX1hcNOkNVzMOEl0ETRUeZkTCU0lnVO1s

表格数据

email: hihi@gmail.com
password1: test123T
password2: test123T

我的后端经常出错,说不存在CSRF令牌,但是不再发生该错误。

我也遇到了一个障碍,我的前端将被“禁止”,但是这种情况不再发生。

当我检查Django用户数据库时,未添加任何用户:(

如果我启动邮递员,则可以毫无问题地添加用户。

邮递员信息

POST /accounts/signup/ HTTP/1.1
Host: localhost:8000
X-CSRFToken: F8MuraVaDK3tUDwD39lVPthQgdkL4HPm
Content-Type: application/x-www-form-urlencoded
cache-control: no-cache
Postman-Token: d34b79e6-fd5b-44a2-9ed0-74d28fee882e
email=test%40gmail.compassword1=test123Tpassword2=test123T

我开始为此感到疲惫不堪。所以我希望有一些很棒的人能帮我解除障碍。

如果您想克隆/提取存储库,请告诉我。

0 个答案:

没有答案