bounty将在6天后过期。回答此问题可获得+100的声誉奖励。Dave正在寻找来自声誉良好的来源的答案。
我使用Django 3.1.1和Django的auth contrib模块来管理用户。我没有使用Django模板,而是创建了一个Django API应用程序来响应来自React前端的请求。我在www.example.com文件中有这个settings.py
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']
我在我的www.example.com文件中设置了这个views.py
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)
在我的前端,我使用这个获取代码向后端提交密码重置请求
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)
}
})
}
问题是,我第一次提交表单时没有CSRF令牌,因为Django没有为我的React应用提供服务(它是由Apache提供的)。我如何从Django获得CSRF令牌,以便在提交密码重置表单时可以将其提交回来?
1条答案
按热度按时间h43kikqp1#
这个答案在JS/ReactJS中没有实现,但是它有关于如何实现它们的一般说明。
如果您访问了
TemplateResponse
渲染的有效视图,Django将返回CSRF令牌和cookie。要获得CSRF令牌,您需要发送HTTP GET
请求到相同的URL(response may look like this)。完成请求后,您将在cookie部分获得CSRF令牌。在这里,我用Python的
requests
库演示了一个简单的示例。