我在Django REST Framework中使用TokenAuthentication让脚本远程访问我的API。运行API的域位于TLS证书后面。
我已经浏览了很多来源,并在来到这里找出我的问题之前尝试了很多选择。简而言之,当我尝试发布时,我会继续收到public class IncrementIntProcessor implements Processor {
private String headerName;
private int delta = 1;
public IncrementIntProcessor(String headerName){
this.headerName = headerName;
}
public IncrementIntProcessor(String headerName, int delta){
this.headerName = headerName;
this.delta = delta;
}
@Override
public void process(Exchange exchange) throws Exception {
int num = (exchange.getIn().getHeader(headerName)==null ? 0 : exchange.getIn().getHeader(headerName, Integer.class));
exchange.getIn().setHeader(headerName, (num+delta));
}
}
错误。
以下是我的观点:
....
.process(new IncrementIntProcessor("intHeader", 50))
.log(LoggingLevel.INFO, "${header.intHeader}")
....
CSRF verification failed. Request aborted.
装饰者在这里什么也没做。所以,我也在# @csrf_exempt
@api_view(['POST'])
@authentication_classes((TokenAuthentication,))
@permission_classes((permissions.IsAuthenticated,))
def create_object(request):
上尝试了它:
csrf_exempt
我甚至尝试过编写自定义装饰器,并使用this suggestion。即使我这样做,我甚至无法在失败之前让装饰器执行。也许我的中间件订购存在问题?
urls.py
以下是我的django cors设置:
url(r'^create_object/', csrf_exempt(views.create_object),),
答案 0 :(得分:2)
正如所承诺的,这是我提出的解决方案。不可否认,这并不完美。我无法找出潜在的问题(为什么在HTTPS上应用程序没有响应csrf_exempt
或CORS_REPLACE_HTTPS_REFERER
),但提出了这个有限的解决方案。
第1步
首先,我将整个CsrfViewMiddleware
类子类化为我自己的版本,并将其放入我的中间件(标记为原始序列的更改):
'sslify.middleware.SSLifyMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware', ##CHANGE
'myapp.csrf.CsrfViewMiddleware', ##CHANGE
'corsheaders.middleware.CorsPostCsrfMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
在CsrfViewMiddleware
的我的版本第160行,我将现有条件替换为:
acceptable_referers = ['https://%s' % u for u in settings.CORS_ORIGIN_WHITELIST] + ['http://%s' % u for u in settings.CORS_ORIGIN_WHITELIST]
if not same_origin(referer, good_referer) and referer not in acceptable_referers:
这让我超越了无效的引用者问题,这很好,因为我将域名列入白名单。它基本上与CORS_REPLACE_HTTPS_REFERER
的结果相同。我的版本使用settings.CORS_ORIGIN_WHITELIST
交叉引用了引用标头,而CORS_REPLACE_HTTPS_REFERER
方法暂时更改了request
引用者。在我看来,似乎没有足够的安全解决方案 - 但这是另一个对话。
第2步
此时,我仍然收到csrf cookie not found错误。为了避免这个问题,并且由于csrf_exempt
没有重新编码(好像中间件执行得太早),我添加了一个新的中间件:
'sslify.middleware.SSLifyMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'myapp.csrf.CsrfSkipMiddleware' ##ADDED
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware', ##REMOVED
'myapp.csrf.CsrfViewMiddleware', ##ADDED
'corsheaders.middleware.CorsPostCsrfMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
这个新的中间件实际上在请求对象(_dont_enforce_csrf_checks
)上设置了一个标志,该标志已存在于CsrfViewMiddleware
的库存版本上,并告诉脚本忽略其余的csrf检查。为此,它会根据我选择从settings.CSRF_SKIP_URLS
中的csrf中删除的路径列表检查页面路径。
class CsrfSkipMiddleware(object):
def process_request(self, request):
CSRF_SKIP_URLS = [re.compile(expr) for expr in settings.CSRF_SKIP_URLS]
path = request.path_info.lstrip('/')
if any(m.match(path) for m in CSRF_SKIP_URLS):
setattr(request, '_dont_enforce_csrf_checks', True)
<强> THOUGHTS 强>
同样,不是最佳实施。但是,为了我的目的,它是有效的。仍然欢迎思考。
答案 1 :(得分:0)
我看到你正在使用django cors标头。
我遇到了类似的问题,并指出:
CORS_REPLACE_HTTPS_REFERER = True
settings.py
解决了问题。