I'm using Django 3.1.1 with Django's auth contrib module for managing users. I'm not using Django templates, but rather creating a Django API application to respond to requests from my React frontend. I have this in my settings.py file
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',
'directory.middleware.extend_token_response.ExtendTokenResponse'
]
#CORS_ORIGIN_ALLOW_ALL = True
ALLOWED_HOSTS = ['127.0.0.1', 'localhost', 'dev.mywebsite.com', 'prod.mywebsite.com', 'map.mywebsite.com']
CORS_ORIGIN_WHITELIST = [
'http://localhost:3000', 'http://localhost:3001', 'http://127.0.0.1:3000', 'http://127.0.0.1:3001'
]
CORS_EXPOSE_HEADERS = [
'Refresh-Token', 'Content-Type', 'Authorization', 'X-CSRFToken'
]
CORS_ALLOW_CREDENTIALS = True
CSRF_TRUSTED_ORIGINS = ['localhost', '127.0.0.1']
I have this set up in my views.py file
class ResetPasswordView(SuccessMessageMixin, PasswordResetView):
email_template_name = 'users/password_reset_email.html'
subject_template_name = 'users/password_reset_subject'
success_message = "We've emailed you instructions for setting your password, " \
"if an account exists with the email you entered. You should receive them shortly." \
" If you don't receive an email, " \
"please make sure you've entered the address you registered with, and check your spam folder."
success_url = reverse_lazy('users-home')
def post(self, request, *args, **kwargs):
print("request data %s" % request.data)
email = request.data.get('email')
try:
if User.objects.get(email=email).active:
print("email: %s " % email)
return super(ResetPasswordView, self).post(request, *args, **kwargs)
except:
# this for if the email is not in the db of the system
return super(ResetPasswordView, self).post(request, *args, **kwargs)
In my frontend, I submit password reset requests to my backend using this fetch code
const handleFormSubmit = (e) => {
e.preventDefault()
const csrftoken = getCsrfToken();
fetch(REACT_APP_PROXY + '/reset_password', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({username})
}).then(resp => resp.json())
.then(jsob => {
if(!jsob.ok){
console.log(jsob)
setErrors(jsob)
}
if(jsob.token){
sessionStorage.setItem('token', jsob.token)
setRedirect(true)
}
})
}
The problem is, I don't have a CSRF token the first time I submit the form because Django is not serving my React application (it is served by Apache). How do I get a CSRF token from Django so that I can submit it back during the submission of my password reset form?