Django开发环境中使用https(未设置有效证书)的“禁止(未设置CSRF cookie)。”

时间:2020-11-02 17:35:02

标签: django csrf

可以肯定的是,这是我在开发环境中遇到Forbidden (CSRF cookie not set.)错误的原因:

  • 致力于Azure AD身份验证
  • URI重定向需要localhosthttps://
  • 由于我正在使用k8s在本地skaffold集群中进行开发,因此它具有与minikube ip类似的192.168.64.7
  • 因此,我必须进行https://192.168.64.7/的URI重定向,因为我只是在开发人员中,所以不使用有效的SSL证书
  • 我正要从React FE向我们的API发送accessToken,以便在那里再次进行验证
  • 非常确定Django正在看到https://,并且它无效导致此错误

所以我的问题是:

  • 我是否更正为什么会出现此错误?
  • 是否可以在开发中启用忽略此设置?
  • 还是为我的开发环境获取有效SSL证书的唯一选择?

我已确认无法执行以下操作:

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')

再次,这样做不是一个好主意...

我确实设法为我的开发环境实现了一个证书,以为它可以解决问题,但是仍然存在。

建议?

1 个答案:

答案 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):

  1. 确定要提供应用程序的DNS名称,并将其添加到/etc/hosts并将其映射到minikube ip(是的,很遗憾,如果执行{{1 }}。就我而言,是:
minikube delete

然后刷新您的本地DNS。在macOS上是:

192.168.64.7      companyapp.local
  1. 更新您的开发人员sudo killall -HUP mDNSResponder 以使用ingress-nginx.yaml。我本来不是在开发入口中这样做的。我结束了:
hosts
  1. 安装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
  1. 安装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
  1. 使用来自kubectl get pods --namespace cert-manager 的证书进行k8s秘密输入:
mkcert

执行此操作后,您应该可以删除kubectl create secret tls tls-companyapp-dev --key=companyapp.local-key.pem --cert=companyapp.local.pem 文件。

  1. 制作.pemIssuer清单并应用它们:
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 并且它具有有效的证书。不再需要处理“不安全”消息。

所有这些...仍然无法解决我的问题。