我有一个带有 django
的 web 应用程序,它有一个使用 django-rest-framework
提供 API 的模块移动应用。
如果我登录到网络应用,移动应用上的csrf
token 会向我抛出一个403 - Forbiden
,响应如下
{"detail":"CSRF Failed: CSRF token missing or incorrect."}
当我从网络应用程序注销时,我可以再次使用移动应用程序(即使没有再次登录,在第一个 session 中)。
我有以下关于 django-rest-framework-jwt
CORS_ORIGIN_ALLOW_ALL = True
CORS_URLS_REGEX = r'^/api/v1/.*$'
CORS_ALLOW_CREDENTIALS = True
JWT_AUTH = {
'JWT_SECRET_KEY': SECRET_KEY,
'JWT_ALGORITHM': 'HS256',
'JWT_VERIFY': True,
'JWT_VERIFY_EXPIRATION': True,
'JWT_LEEWAY': 0,
'JWT_EXPIRATION_DELTA': timedelta(days=120),
'JWT_AUDIENCE': None,
'JWT_ISSUER': None,
'JWT_ALLOW_REFRESH': True,
'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=7),
'JWT_AUTH_HEADER_PREFIX': 'JWT',
}
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)
}
最后是 INSTALLED_APPS
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
'django.contrib.admindocs',
'djangotoolbox',
'autoload',
'dbindexer',
'gaeblob_storage',
################################## WEB APP MODULES
'myapp.modulos.presentacion',
'myapp.modulos.principal',
'myapp.modulos.proyecto',
'myapp.modulos.estado_1',
'myapp.modulos.estado_2',
'myapp.modulos.estado_3',
'myapp.modulos.comunicacion',
################################## API MODULE
'myapp.modulos.api',
'django_forms_bootstrap',
# API Rest
'jwt',
'rest_framework',
'rest_framework_jwt',
'corsheaders',
'django_filters',
# djangoappengine should come last, so it can override a few manage.py commands
'djangoappengine',
)
这里也是登录 View ,
def login_view(request):
status = ""
if request.user.is_authenticated():
return redirect('/principal') #Cambiar cuando este el estado disponible
else:
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None and user.is_active:
login(request, user)
FLOW.params['state'] = xsrfutil.generate_token(settings.SECRET_KEY,request.user)
authorize_url = FLOW.step1_get_authorize_url()
return HttpResponseRedirect(authorize_url)
else:
status = "Usuario y/o Password incorrecto"
form = LoginForm()
ctx = {'form':form, 'status': status}
return render(request,'presentacion/login.html',ctx)
return render(request,'presentacion/login.html')
最佳答案
“默认情况下,如果传入请求未通过 CsrfViewMiddleware 执行的检查,则会向用户发送‘403 Forbidden’响应。通常只有在存在真正的跨站点请求伪造时,或者由于编程错误,POST 表单中未包含 CSRF token 。” https://docs.djangoproject.com/en/1.8/ref/csrf/#rejected-requests
您需要在请求的表单数据中包含 csrf
token 。
如果 CSRF_COOKIE_HTTPONLY,您可以从 cookie 或 DOM 中获取它= 正确。
有关详细信息,请参阅 Django's AJAX docs .
关于python - Django + Django REST csrf on AJAX direfent 站点请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30585501/