可以肯定的是,这是我在开发环境中遇到Forbidden (CSRF cookie not set.)
错误的原因:
localhost
或https://
k8s
在本地skaffold
集群中进行开发,因此它具有与minikube ip
类似的192.168.64.7
https://192.168.64.7/
的URI重定向,因为我只是在开发人员中,所以不使用有效的SSL证书accessToken
,以便在那里再次进行验证https://
,并且它无效导致此错误所以我的问题是:
我已确认无法执行以下操作:
ALLOWED_HOSTS = [
'*'
]
另外,GET
个请求有效,但POST
个请求无效。
#views.py
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse
# Create your views here.
class TestView(View):
def post(self, request):
return HttpResponse('Hello World')
// Authentication.js
const testApiAuthentication = async () => {
let accessToken = await authProvider.getAccessToken();
setAccessToken(accessToken.accessToken);
if (accessToken) {
setAuthenticatingToken(true);
axios({
method: 'post',
url: '/api/users/',
headers: {
Authorization: 'Bearer ' + accessToken,
},
})
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
}
};
编辑:
以下是一个选择(不是一个好的选择),以使其免于CSRF。
from django.views import View
from django.http import HttpResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
# Create your views here.
@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
def post(self, request):
return HttpResponse('Hello World')
再次,这样做不是一个好主意...
我确实设法为我的开发环境实现了一个证书,以为它可以解决问题,但是仍然存在。
建议?
答案 0 :(得分:0)
发现问题是我需要使用django-rest-framework
,因为从我的阅读来看,它内置了CSRF免责条款。我以为我会使用Django视图来对此进行快速测试,但是事实证明导致问题。 需要使用DRF。
@csrf_exempt
的任何人使用基于类的视图或在本地开发k8s集群中实现TLS。正如我所指出的,以下是一种选择(而不是好的选择),以使其免于CSRF。
from django.views import View
from django.http import HttpResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
# Create your views here.
@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
def post(self, request):
return HttpResponse('Hello World')
对我有用的TLS实现如下(主要基于this blog article):
/etc/hosts
并将其映射到minikube ip
(是的,很遗憾,如果执行{{1 }}。就我而言,是:minikube delete
然后刷新您的本地DNS。在macOS上是:
192.168.64.7 companyapp.local
sudo killall -HUP mDNSResponder
以使用ingress-nginx.yaml
。我本来不是在开发入口中这样做的。我结束了:hosts
mkcert
并生成证书(请参见您的操作系统的链接):apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: 'nginx'
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^(/admin)$ $1/ permanent;
name: ingress-service-dev
namespace: default
spec:
tls:
- hosts:
- companyapp.local
secretName: tls-companyapp-dev
rules:
- host: companyapp.local
http:
paths:
- path: /admin/
backend:
serviceName: admin-cluster-ip-service-dev
servicePort: 4000
- path: /api/
backend:
serviceName: api-cluster-ip-service-dev
servicePort: 5000
- path: /
backend:
serviceName: client-cluster-ip-service-dev
servicePort: 3000
cert-manager
:brew install mkcert
brew install nss # if you use Firefox
mkcert -install
mkcert companyapp.local
等待直到Pod准备使用以下命令进行检查:
# Kubernetes 1.16+
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.4/cert-manager.yaml
# Kubernetes <1.16
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.4/cert-manager-legacy.yaml
kubectl get pods --namespace cert-manager
的证书进行k8s秘密输入:mkcert
执行此操作后,您应该可以删除kubectl create secret tls tls-companyapp-dev --key=companyapp.local-key.pem --cert=companyapp.local.pem
文件。
.pem
和Issuer
清单并应用它们:Certificate
并应用它们:
# issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-dev-issuer
namespace: cert-manager
spec:
ca:
secretName: tls-companyapp-dev
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: letsencrypt-dev-certificate
namespace: cert-manager
spec:
secretName: tls-companyapp-dev
dnsNames:
- companyapp.local
issuerRef:
name: letsencrypt-dev-issuer
kind: Issuer
进行了几次尝试,但是最终我能够导航到kubectl apply -f <manifest_location>/issuer.yaml
并且它具有有效的证书。不再需要处理“不安全”消息。
所有这些...仍然无法解决我的问题。