TandoorRecipes / recipes

Application for managing recipes, planning meals, building shopping lists and much much more!
https://docs.tandoor.dev
Other
5.55k stars 589 forks source link

There was an error fetching a resource! {"detail":"Authentication credentials were not provided."} #2835

Closed leon1995 closed 10 months ago

leon1995 commented 10 months ago

Tandoor Version

abf8f791360b2bc4a5c7d011877668679bcbb3f2

Setup

Manual Setup

Reverse Proxy

Nginx Proxy Manager (NPM)

Other

No response

Bug description

After creating a recipe and get redirected to edit/recipe/internal/<id>I encounter the error (multiple times) There was an error fetching a resource! {"detail":"Authentication credentials were not provided."}. Screenshot 2023-12-27 at 20 22 55 In the django admin site I can see the created recipes.

I also get this on other sites, e.g. before I can create a book or open the shopping list site

Relevant logs

There are no nginx error logs
smilerz commented 10 months ago

Your headers are probably wrong. please share details on your setup, configuration details and the headers listed under 'Debug' on the System page.

leon1995 commented 10 months ago

Hey, thanks for the quick answer. Here ther requested information

tandoor nginx conf

server {
    listen 8002;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    # serve media files
    location /static/ {
        alias /var/www/recipes/staticfiles/;
    }

    location /staticfiles/ {
        alias /var/www/recipes/staticfiles/;
    }

    location /media/ {
        alias /var/www/recipes/mediafiles/;
    }

    location /mediafiles/ {
        alias /var/www/recipes/mediafiles/;
    }

    location / {
        proxy_set_header Host $http_host;
        proxy_pass http://unix:/var/www/recipes/recipes.sock;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

npm nginx conf

server {
  set $forward_scheme http;
  set $server         "10.10.1.51";
  set $port           8002;

listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
  server_name mydomain;
  # Let's Encrypt SSL
  include conf.d/include/letsencrypt-acme-challenge.conf;
  include conf.d/include/ssl-ciphers.conf;
  ssl_certificate /etc/letsencrypt/live/npm-36/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/npm-36/privkey.pem;
# Asset Caching
  include conf.d/include/assets.conf;
  # Block Exploits
  include conf.d/include/block-exploits.conf;
  # HSTS (ngx_http_headers_module is required) (63072000 seconds = 2 years)
  add_header Strict-Transport-Security "max-age=63072000;includeSubDomains; preload" always;
    # Force SSL
    include conf.d/include/force-ssl.conf;
  access_log /data/logs/proxy-host-23_access.log proxy;
  error_log /data/logs/proxy-host-23_error.log warn;
  location / {
    # Proxy!
    include conf.d/include/proxy.conf;
  }
  # Custom
  include /data/nginx/custom/server_proxy[.]conf;
}

headers

Gunicorn Media: False
Sqlite: True
Debug: True

SERVER_PROTOCOL:HTTP/1.0
REMOTE_ADDR:
SERVER_PORT:80

HTTP_HOST:mydomain
HTTP_X_FORWARDED_PROTO:http
HTTP_CONNECTION:close
HTTP_X_FORWARDED_SCHEME:https
HTTP_X_FORWARDED_FOR:redacted
HTTP_X_REAL_IP:redacted
HTTP_CDN_LOOP:cloudflare
HTTP_CF_IPCOUNTRY:DE
HTTP_ACCEPT_ENCODING:gzip
HTTP_CF_RAY:83c42717bee662c6-HAM
HTTP_CF_VISITOR:{"scheme":"https"}
HTTP_USER_AGENT:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0
HTTP_ACCEPT:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
HTTP_ACCEPT_LANGUAGE:en-US,en;q=0.5
HTTP_REFERER:https://mydomain/list/shopping-list/
HTTP_DNT:1
HTTP_UPGRADE_INSECURE_REQUESTS:1
HTTP_SEC_FETCH_DEST:document
HTTP_SEC_FETCH_MODE:navigate
HTTP_SEC_FETCH_SITE:same-origin
HTTP_SEC_FETCH_USER:?1
HTTP_SEC_GPC:1
HTTP_CF_CONNECTING_IP:redacted
HTTP_COOKIE:csrftoken=redacted

wsgi.errors:<gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7f69372a0eb0>
wsgi.version:(1, 0)
wsgi.multithread:False
wsgi.multiprocess:False
wsgi.run_once:False
wsgi.file_wrapper:
wsgi.input_terminated:True
wsgi.input:<gunicorn.http.body.Body object at 0x7f69371c7e50>
wsgi.url_scheme:http

.env

# only set this to true when testing/debugging
# when unset: 1 (true) - dont unset this, just for development
DEBUG=1
SQL_DEBUG=0
DEBUG_TOOLBAR=0
# Gunicorn log level for debugging (default value is "info" when unset)
# (see https://docs.gunicorn.org/en/stable/settings.html#loglevel for available settings)
# GUNICORN_LOG_LEVEL="debug"

# HTTP port to bind to
# TANDOOR_PORT=8080

# hosts the application can run under e.g. recipes.mydomain.com,cooking.mydomain.com,...
ALLOWED_HOSTS=mydomain

# Cross Site Request Forgery protection
# (https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS)
CSRF_TRUSTED_ORIGINS="https://mydomain"

# Cross Origin Resource Sharing
# (https://github.com/adamchainz/django-cors-header)
#CORS_ALLOW_ALL_ORIGINS=True

# random secret key, use for example `base64 /dev/urandom | head -c50` to generate one
# ---------------------------- AT LEAST ONE REQUIRED -------------------------
SECRET_KEY=redacted
SECRET_KEY_FILE=
# ---------------------------------------------------------------

# your default timezone See https://timezonedb.com/time-zones for a list of timezones
TZ=Europe/Berlin

# add only a database password if you want to run with the default postgres, otherwise change settings accordingly
DB_ENGINE=django.db.backends.postgresql
# DB_OPTIONS= {} # e.g. {"sslmode":"require"} to enable ssl
POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=5432
POSTGRES_USER=djangouser
# ---------------------------- AT LEAST ONE REQUIRED -------------------------
POSTGRES_PASSWORD=redacted
POSTGRES_PASSWORD_FILE=
# ---------------------------------------------------------------
POSTGRES_DB=djangodb

# database connection string, when used overrides other database settings.
# format might vary depending on backend
# DATABASE_URL = engine://username:password@host:port/dbname

# the default value for the user preference 'fractions' (enable/disable fraction support)
# default: disabled=0
FRACTION_PREF_DEFAULT=0

# the default value for the user preference 'comments' (enable/disable commenting system)
# default comments enabled=1
COMMENT_PREF_DEFAULT=1

# Users can set a amount of time after which the shopping list is refreshed when they are in viewing mode
# This is the minimum interval users can set. Setting this to low will allow users to refresh very frequently which
# might cause high load on the server. (Technically they can obviously refresh as often as they want with their own scripts)
SHOPPING_MIN_AUTOSYNC_INTERVAL=5

# Default for user setting sticky navbar
# STICKY_NAV_PREF_DEFAULT=1

# If base URL is something other than just / (you are serving a subfolder in your proxy for instance http://recipe_app/recipes/)
# Be sure to not have a trailing slash: e.g. '/recipes' instead of '/recipes/'
# SCRIPT_NAME=/recipes

# If staticfiles are stored at a different location uncomment and change accordingly, MUST END IN /
# this is not required if you are just using a subfolder
# This can either be a relative path from the applications base path or the url of an external host
STATIC_URL=/var/www/recipes/staticfiles/

# If mediafiles are stored at a different location uncomment and change accordingly, MUST END IN /
# this is not required if you are just using a subfolder
# This can either be a relative path from the applications base path or the url of an external host
MEDIA_URL=/var/www/recipes/mediafiles/

# Serve mediafiles directly using gunicorn. Basically everyone recommends not doing this. Please use any of the examples
# provided that include an additional nxginx container to handle media file serving.
# If you know what you are doing turn this back on (1) to serve media files using djangos serve() method.
# when unset: 1 (true) - this is temporary until an appropriate amount of time has passed for everyone to migrate
GUNICORN_MEDIA=0

# GUNICORN SERVER RELATED SETTINGS (see https://docs.gunicorn.org/en/stable/design.html#how-many-workers for recommended settings)
# GUNICORN_WORKERS=1
# GUNICORN_THREADS=1

# S3 Media settings: store mediafiles in s3 or any compatible storage backend (e.g. minio)
# as long as S3_ACCESS_KEY is not set S3 features are disabled
# S3_ACCESS_KEY=
# S3_SECRET_ACCESS_KEY=
# S3_BUCKET_NAME=
# S3_REGION_NAME= # default none, set your region might be required
# S3_QUERYSTRING_AUTH=1 # default true, set to 0 to serve media from a public bucket without signed urls
# S3_QUERYSTRING_EXPIRE=3600 # number of seconds querystring are valid for
# S3_ENDPOINT_URL= # when using a custom endpoint like minio
# S3_CUSTOM_DOMAIN= # when using a CDN/proxy to S3 (see https://github.com/TandoorRecipes/recipes/issues/1943)

# Email Settings, see https://docs.djangoproject.com/en/3.2/ref/settings/#email-host
# Required for email confirmation and password reset (automatically activates if host is set)
# EMAIL_HOST=
# EMAIL_PORT=
# EMAIL_HOST_USER=
# EMAIL_HOST_PASSWORD=
# EMAIL_USE_TLS=0
# EMAIL_USE_SSL=0
# email sender address (default 'webmaster@localhost')
# DEFAULT_FROM_EMAIL=
# prefix used for account related emails (default "[Tandoor Recipes] ")
# ACCOUNT_EMAIL_SUBJECT_PREFIX=

# allow authentication via the REMOTE-USER header (can be used for e.g. authelia).
# ATTENTION: Leave off if you don't know what you are doing! Enabling this without proper configuration will enable anybody
#   to login with any username!
# See docs for additional information: https://docs.tandoor.dev/features/authentication/#reverse-proxy-authentication
# when unset: 0 (false)
REMOTE_USER_AUTH=0

# Default settings for spaces, apply per space and can be changed in the admin view
# SPACE_DEFAULT_MAX_RECIPES=0 # 0=unlimited recipes
# SPACE_DEFAULT_MAX_USERS=0 # 0=unlimited users per space
# SPACE_DEFAULT_MAX_FILES=0 # Maximum file storage for space in MB. 0 for unlimited, -1 to disable file upload.
# SPACE_DEFAULT_ALLOW_SHARING=1 # Allow users to share recipes with public links

# allow people to create local accounts on your application instance (without an invite link)
# social accounts will always be able to sign up
# when unset: 0 (false)
ENABLE_SIGNUP=0

# If signup is enabled you might want to add a captcha to it to prevent spam
# HCAPTCHA_SITEKEY=
# HCAPTCHA_SECRET=

# if signup is enabled you might want to provide urls to data protection policies or terms and conditions
# TERMS_URL=
# PRIVACY_URL=
# IMPRINT_URL=

# enable serving of prometheus metrics under the /metrics path
# ATTENTION: view is not secured (as per the prometheus default way) so make sure to secure it
# trough your web server (or leave it open of you dont care if the stats are exposed)
# ENABLE_METRICS=0

# allows you to setup OAuth providers
# see docs for more information https://docs.tandoor.dev/features/authentication/
# SOCIAL_PROVIDERS = allauth.socialaccount.providers.github, allauth.socialaccount.providers.nextcloud,

# Should a newly created user from a social provider get assigned to the default space and given permission by default ?
# ATTENTION: This feature might be deprecated in favor of a space join and public viewing system in the future
# default 0 (false), when 1 (true) users will be assigned space and group
# SOCIAL_DEFAULT_ACCESS = 1

# if SOCIAL_DEFAULT_ACCESS is used, which group should be added
# SOCIAL_DEFAULT_GROUP=guest

# Django session cookie settings. Can be changed to allow a single django application to authenticate several applications
# when running under the same database
# SESSION_COOKIE_DOMAIN=.example.com
# SESSION_COOKIE_NAME=sessionid # use this only to not interfere with non unified django applications under the same top level domain

# by default SORT_TREE_BY_NAME is disabled this will store all Keywords and Food in the order they are created
# enabling this setting makes saving new keywords and foods very slow, which doesn't matter in most usecases.
# however, when doing large imports of recipes that will create new objects, can increase total run time by 10-15x
# Keywords and Food can be manually sorted by name in Admin
# This value can also be temporarily changed in Admin, it will revert the next time the application is started
# This will be fixed/changed in the future by changing the implementation or finding a better workaround for sorting
# SORT_TREE_BY_NAME=0
# LDAP authentication
# default 0 (false), when 1 (true) list of allowed users will be fetched from LDAP server
#LDAP_AUTH=
#AUTH_LDAP_SERVER_URI=
#AUTH_LDAP_BIND_DN=
#AUTH_LDAP_BIND_PASSWORD=
#AUTH_LDAP_USER_SEARCH_BASE_DN=
#AUTH_LDAP_TLS_CACERTFILE=
#AUTH_LDAP_START_TLS=

# Enables exporting PDF (see export docs)
# Disabled by default, uncomment to enable
ENABLE_PDF_EXPORT=1

# Recipe exports are cached for a certain time by default, adjust time if needed
# EXPORT_FILE_CACHE_DURATION=600

# if you want to do many requests to the FDC API you need to get a (free) API key. Demo key is limited to 30 requests / hour or 50 requests / day
FDC_API_KEY=redacted

# API throttle limits
# you may use X per second, minute, hour or day
# DRF_THROTTLE_RECIPE_URL_IMPORT=60/hour
smilerz commented 10 months ago

you are missing HTTP_X_FORWARDED_PROTO

you need to make sure your first proxy is setting proxy_set_header X-Forwarded-Proto $scheme;

leon1995 commented 10 months ago

I do have them in the config include conf.d/include/proxy.conf;:

set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;

set              $targetUri $forward_scheme://$server:$port$request_uri;
add_header       X-Served-By $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto  $scheme;
proxy_set_header X-Forwarded-For    $remote_addr;
proxy_set_header X-Real-IP          $remote_addr;
proxy_pass       $targetUri;
real_ip_header        CF-Connecting-IP;
client_max_body_size 500M;

sorry, I forgot this

smilerz commented 10 months ago

shouldn't the HTTP_X_FORWARDED_PROTObe https? It's hitting Tandoor as http

leon1995 commented 10 months ago

Maybe, because the setup is Internet via https -> npm forward http -> tandoor nginx. Is it possible to run tandoor only using npm? Note, that they dont run on the same host

smilerz commented 10 months ago

proxy_set_header X-Forwarded-Proto $scheme; also needs set in NPM.

You can use any proxy, it doesn't have to be the dedicated tandoor nginx container. it just needs to be able to serve the media content and set the headers defined here.

leon1995 commented 10 months ago

I fixed it. The problem was that the tandoor nginx instance was overwriting the X-Forwarded-Proto header with http. I just removed it in the tandoor nginx config, because the npm nginx config sets it with https. Now its working.

    location / {
        proxy_set_header Host $http_host;
        proxy_pass http://unix:/var/www/recipes/recipes.sock;
    }

Thanks for your help