【问题标题】:SSL/https removes X-CSRFToken from headersSSL/https 从标头中删除 X-CSRFToken
【发布时间】:2017-07-21 01:08:23
【问题描述】:

安装 SSL/https 密钥后,X-CSRFToken 被删除。我还设置了http2。在 Https 之前一切正常,但现在我得到 403,因为缺少 CSRF 令牌。找不到解决此特定问题的信息。感谢您的帮助。

support
  server {
    # Enable HTTP/2
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl on;
    server_name site.io www.site.io;

    # Use the Let's Encrypt certificates
    ssl_certificate /etc/letsencrypt/live/site.io/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/site.io/privkey.pem;

    # Include the SSL configuration from cipherli.st
    include /etc/nginx/snippets/ssl-params.conf;

    add_header Strict-Transport-Security max-age=500;

    access_log /home/nodejs/site.io/resuma_io_access.log;
    error_log /home/nodejs/site.io/resuma_io_error.log;
    root /home/nodejs/site.io/www/dist/client;

     location ~ ^/(api|user|auth|socket.io-client|sitemap.xml) {
          proxy_set_header   X-Real-IP            $remote_addr;
          proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
          proxy_set_header   X-Forwarded-Proto $scheme;
          proxy_set_header   Host                   $http_host;
          proxy_set_header   X-NginX-Proxy    true;
          proxy_set_header Upgrade $http_upgrade;
          proxy_ssl_session_reuse off;
          proxy_redirect off;
          proxy_set_header Connection 'upgrade';
          proxy_cache_bypass $http_upgrade;
          proxy_http_version 1.1;
          proxy_pass_header  X-CSRFToken;
          add_header X-Frame-Options SAMEORIGIN;
          sendfile  off;
          proxy_pass         http://nodejs_upstream;
        }
   }

【问题讨论】:

  • 您能找到解决方法吗?我相信我也有同样的问题。
  • 如果您的设置与上述相同,您可能会在其他地方遇到问题。它对我不起作用,因为 X-CSRF 令牌是由后端在任何第一次请求时生成和设置的。但是由于所有文件都由 nginx 提供,因此在访客用户的初始页面加载时没有请求后端。作为一种解决方法,我发出一个服务器请求以在初始页面加载时创建令牌。

标签: node.js ssl nginx reverse-proxy


【解决方案1】:

我对在 Nginx SSL/https 上运行的 Django 有同样的问题。

正如 Bryan 在 Django CSRF check failing with an Ajax POST request 上提到的。传递 csrftoken 的另一种方法是通过参数传递它:

$.ajax({
data: {
    somedata: 'somedata',
    moredata: 'moredata',
    csrfmiddlewaretoken: mytoken
},

其中csrfmiddlewaretoken代表你的api用来存储csrftoken的变量名(django中的csrfmiddlewaretoken):

mytoken是一个已初始化的变量

  1. DOM:使用您的 api 的令牌命名变量。 在 django 中,只需在您的 html 文件中添加 {% csrf_token %} 。这将提供 csrfmiddlewaretoken 变量,该变量可在 jQuery 中访问

    mytoken = jQuery("[name=csrfmiddlewaretoken]").val();

  2. COOKIE:或者通过使用从 cookie 中获取令牌的 jQuery 函数。

    mytoken = getCookie('csrftoken');

django doc 中提到了 getCookie() 函数,以便用 AJAX 处理 CSRF POST。

当然,这并不能解决 SSL 的标头问题,但允许 POST、PUT 和 DELETE 请求。它还需要通过每个 $.ajax 调用来添加 csrfmiddlewaretoken 变量

【讨论】:

    【解决方案2】:

    通过我上次在 stackoverflow 上的搜索,我找到了问题的真正原因。 就我而言,这不是标题问题,而是 cookie 问题! CSRFToken 不在 cookie 中!

    Wtower 在 2015 年 5 月 13 日在 403 Forbidden error when making an ajax Post request in Django framework 上的回答得到了明确的解释。

    settings.py 中的CSRF_COOKIE_HTTPONLY = True 必须删除或设置为False

    如果设置为 True,客户端 JavaScript 将无法访问 CSRF cookie!

    【讨论】:

      猜你喜欢
      • 2013-04-14
      • 2016-03-08
      • 2017-09-18
      • 1970-01-01
      • 1970-01-01
      • 2021-03-13
      • 1970-01-01
      • 2016-10-10
      • 2010-11-02
      相关资源
      最近更新 更多