ошибка неправильного запроса 400 с asp .net core, размещенным с Dokku на DigitalOcean

#asp.net-core #nginx-config #dokku

#asp.net-core #nginx-config #dokku

Вопрос:

У меня проблема с моим веб-api asp .net core. Я настроил авторизацию с помощью jwt. На локальном хосте все работает отлично. Когда я загружаю в Dokku, я не могу отправить сообщение на сервер, я получаю 400.

Вот моя конфигурация nginx, которая создается из файла sigil:

 {{ range $port_map := .PROXY_PORT_MAP | split " " }}
{{ $port_map_list := $port_map | split ":" }}
{{ $scheme := index $port_map_list 0 }}
{{ $listen_port := index $port_map_list 1 }}
{{ $upstream_port := index $port_map_list 2 }}

{{ if eq $scheme "http" }}
server {
  listen      [::]:{{ $listen_port }};
  listen      {{ $listen_port }};
  {{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }}
  access_log  /var/log/nginx/{{ $.APP }}-access.log;
  error_log   /var/log/nginx/{{ $.APP }}-error.log;
{{ if (and (eq $listen_port "80") ($.SSL_INUSE)) }}
  return 301 https://$host:{{ $.PROXY_SSL_PORT }}$request_uri;
{{ else }}
  location    / {

    ###CORS-START###
    if ($request_method = 'OPTIONS') {
       add_header 'Access-Control-Allow-Origin' '*';
       add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
       #
       # Custom headers and headers various browsers *should* be OK with but aren't
       #
       add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
       #
       # Tell client that this pre-flight info is valid for 20 days
       #
       add_header 'Access-Control-Max-Age' 1728000;
       add_header 'Content-Type' 'text/plain; charset=utf-8';
       add_header 'Content-Length' 0;
       return 204;
    }
    if ($request_method = 'POST') {
       add_header 'Access-Control-Allow-Origin' '*';
       add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
       add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
       add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    }
    if ($request_method = 'GET') {
       add_header 'Access-Control-Allow-Origin' '*';
       add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
       add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
       add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    }
    ###CORS-END###

    gzip on;
    gzip_min_length  1100;
    gzip_buffers  4 32k;
    gzip_types    text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml  application/rss xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg xml;
    gzip_vary on;
    gzip_comp_level  6;

    proxy_pass  http://{{ $.APP }}-{{ $upstream_port }};
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_set_header X-Request-Start $msec;

    proxy_set_header 'Access-Control-Max-Age' 1728000;
    proxy_set_header 'Access-Control-Allow-Origin' '*';
    proxy_set_header 'Access-Control-Allow-Credentials' 'true';
    proxy_set_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    proxy_set_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
  }
  include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;

  error_page 400 401 402 403 405 406 407 408 409 410 411 412 413 414 415 416 417 418 420 422 423 424 426 428 429 431 444 449 450 451 /400-error.html;
  location /400-error.html {
    root {{ $.DOKKU_LIB_ROOT }}/data/nginx-vhosts/dokku-errors;
    internal;
  }

  error_page 404 /404-error.html;
  location /404-error.html {
    root {{ $.DOKKU_LIB_ROOT }}/data/nginx-vhosts/dokku-errors;
    internal;
  }

  error_page 500 501 502 503 504 505 506 507 508 509 510 511 /500-error.html;
  location /500-error.html {
    root {{ $.DOKKU_LIB_ROOT }}/data/nginx-vhosts/dokku-errors;
    internal;
  }
{{ end }}
}
{{ else if eq $scheme "https"}}
server {
  listen      [::]:{{ $listen_port }} ssl {{ if eq $.HTTP2_SUPPORTED "true" }}http2{{ else if eq $.SPDY_SUPPORTED "true" }}spdy{{ end }};
  listen      {{ $listen_port }} ssl {{ if eq $.HTTP2_SUPPORTED "true" }}http2{{ else if eq $.SPDY_SUPPORTED "true" }}spdy{{ end }};
  {{ if $.SSL_SERVER_NAME }}server_name {{ $.SSL_SERVER_NAME }}; {{ end }}
  {{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }}
  access_log  /var/log/nginx/{{ $.APP }}-access.log;
  error_log   /var/log/nginx/{{ $.APP }}-error.log;

  ssl_certificate     {{ $.APP_SSL_PATH }}/server.crt;
  ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key;
  ssl_protocols       TLSv1.2;
  ssl_prefer_server_ciphers on;

  keepalive_timeout   70;
  {{ if and (eq $.SPDY_SUPPORTED "true") (ne $.HTTP2_SUPPORTED "true") }}add_header          Alternate-Protocol  {{ $.PROXY_SSL_PORT }}:npn-spdy/2;{{ end }}

  location    / {

    ###CORS-START###
    if ($request_method = 'OPTIONS') {
       add_header 'Access-Control-Allow-Origin' '*';
       add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
       #
       # Custom headers and headers various browsers *should* be OK with but aren't
       #
       add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
       #
       # Tell client that this pre-flight info is valid for 20 days
       #
       add_header 'Access-Control-Max-Age' 1728000;
       add_header 'Content-Type' 'text/plain; charset=utf-8';
       add_header 'Content-Length' 0;
       return 204;
    }
    if ($request_method = 'POST') {
       add_header 'Access-Control-Allow-Origin' '*';
       add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
       add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
       add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    }
    if ($request_method = 'GET') {
       add_header 'Access-Control-Allow-Origin' '*';
       add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
       add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,,Authorization';
       add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    }
    ###CORS-END###
    gzip on;
    gzip_min_length  1100;
    gzip_buffers  4 32k;
    gzip_types    text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml  application/rss xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg xml;
    gzip_vary on;
    gzip_comp_level  6;

    proxy_pass  http://{{ $.APP }}-{{ $upstream_port }};
    {{ if eq $.HTTP2_PUSH_SUPPORTED "true" }}http2_push_preload on; {{ end }}
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_set_header X-Request-Start $msec;
    proxy_set_header 'Access-Control-Max-Age' 1728000;
    proxy_set_header 'Access-Control-Allow-Origin' '*';
    proxy_set_header 'Access-Control-Allow-Credentials' 'true';
    proxy_set_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    proxy_set_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
  }
  include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;

  error_page 400 401 402 403 405 406 407 408 409 410 411 412 413 414 415 416 417 418 420 422 423 424 426 428 429 431 444 449 450 451 /400-error.html;
  location /400-error.html {
    root {{ $.DOKKU_LIB_ROOT }}/data/nginx-vhosts/dokku-errors;
    internal;
  }

  error_page 404 /404-error.html;
  location /404-error.html {
    root {{ $.DOKKU_LIB_ROOT }}/data/nginx-vhosts/dokku-errors;
    internal;
  }

  error_page 500 501 502 503 504 505 506 507 508 509 510 511 /500-error.html;
  location /500-error.html {
    root {{ $.DOKKU_LIB_ROOT }}/data/nginx-vhosts/dokku-errors;
    internal;
  }
}
{{ end }}{{ end }}

{{ if $.DOKKU_APP_LISTENERS }}
{{ range $upstream_port := $.PROXY_UPSTREAM_PORTS | split " " }}
upstream {{ $.APP }}-{{ $upstream_port }} {
{{ range $listeners := $.DOKKU_APP_LISTENERS | split " " }}
{{ $listener_list := $listeners | split ":" }}
{{ $listener_ip := index $listener_list 0 }}
  server {{ $listener_ip }}:{{ $upstream_port }};{{ end }}
}
{{ end }}{{ end }}
  

В приложении asp cors включен, и все разрешено.

@РЕДАКТИРОВАТЬ

Проблема есть. Когда я запускаю локально свое приложение (asp .net core) в IIS Express, с методом post все в порядке. Как только он загружается в digital ocean в dokku, я получаю 400. Я отправляю те же данные с помощью postaman на мой локальный IIS Express и в Dokku. Я думаю, что это связано с nginx или dokku. Я использую контейнер docker. Я думаю, что это проблема CORS.

Комментарии:

1. У вас проблема с ошибочным запросом 400. Единственная причина, по которой ваш браузер сообщает об этом сообщение, связанное с CORS, заключается в том, что ваш сервер не включает заголовок Access-Control-Allow-Origin в ответ на ошибку 400. Серверы по умолчанию обычно заканчивают тем, что добавляют ваши пользовательские заголовки набора приложений к 2xx. Но даже если ошибка 400 включает заголовок Access-Control-Allow-Origin, у вас все равно будет проблема 400, которую нужно исправить. Таким образом, в этом случае фрагмент CORS-config из вашего серверного кода не очень актуален. Вместо этого более уместным будет фрагмент вашего интерфейса JavaScript-кода.

2. Проблема есть. Когда я запускаю локально свое приложение (asp .net core) в IIS Express, тогда с методом post все в порядке. Как только он загружается в digital ocean в dokku, я получаю 400. Я отправляю те же данные с помощью postaman на мой локальный IIS Express и в Dokku. Я думаю, что это связано с nginx или dokku. Я использую контейнер docker. Я думаю, что это проблема CORS.

3. Какие точные сообщения об ошибках браузер регистрирует в консоли devtools? Какие сообщения сервер-получатель регистрирует в журналах сервера на стороне сервера, прежде чем он ответит 400?

Ответ №1:

Решение было простым. При использовании Docker вы также используете nginx. Я предоставил только один порт из моего приложения asp .net core. Это был http one. Nginx пытался перейти на https, и это не удалось сделать, потому что для docker не было порта ssl. Удалите обновление из конфигурации nginx при открытии только http-порта

Комментарии:

1. Можете ли вы объяснить, как вы это сделали? «Удалить обновление из конфигурации nginx при открытии только http-порта»

2. Dokku позволяет добавлять пользовательские конфигурации nginx для каждого приложения. Добавьте файл nginx в папку приложения в образе docker, и dokku будет использовать ваш шаблон. Существует ссылка на документы dokku: dokku. viewdocs.io/dokku/configuration/nginx /…