REQ and USER are undefined running behind nginx proxy

default discord avatar
gonzam88
last year
1 4

I'm having several issues setting up Payload cms behind an Nginx Proxy for production. Basically my admin user is getting a lot of 403 Forbidden responses from the API, like . Doing some tests I console logged my req, and user variables in the update access hook of a collection, both resulting in undefined. Log-in to admin works, but log-out is weird.
Sometimes, even https://site.com/api/access returns {"errors":[{"message":"req is not defined"}]}
Here´s my configuration file with of course redacted sensitive information

Nginx configuration

server {
    root /var/www/site/dist;
    index index.html index.htm index.nginx-debian.html;
    server_name site.com www.site.com;

    # Static Root
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Payload API
    location /api {
        proxy_pass http://localhost:1336/api;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        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 Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass_request_headers on;
        proxy_set_header Host $host;
    }

    # Payload Admin Dashboard
    location /admin {
        proxy_pass http://localhost:1336/admin;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        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 Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass_request_headers on;
    }

    # Socket.IO
    location /socket.io {
        proxy_pass http://localhost:1336/socket.io;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        # proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

payload.config.js

import { buildConfig } from 'payload/config';
import path from 'path';

// Globals
import Setup from './globals/Setup';
import Avatars from './globals/Avatars';

// Collections
import Admins from './collections/Admins';
import Users from './collections/Users';
import Achievements from './collections/Achievements';
import Experiences from './collections/Experiences';
import Spaces from './collections/Spaces';
import Playlists from './collections/Playlists';
import Images from './collections/Images';
import Videos from './collections/Videos';
import Categories from './collections/Categories';
import Sections from './collections/Sections'

// Graphics
import Logo from './graphics/Logo';
import Icon from './graphics/Icon';

export default buildConfig({
  serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL,
  cors: '*',
  admin: {
    user: Admins.slug,
    css: path.resolve(__dirname, './styles/style.scss'),
    scss: path.resolve(__dirname, './styles/vars.scss'),
    meta: {
        favicon: '/public/favicon.png'
    },
    components: {
       graphics: {
        Logo,
        Icon,
       },
     },
  },
  debug: process.env.PAYLOAD_PUBLIC_DEBUG,
  globals: [
    Setup,
    Avatars,
  ],
  collections: [
    Categories,
    Sections,
    Spaces,
    Experiences,
    Playlists,
    Images, Videos,
    Users,
    Achievements,
    Admins
    // Add Collections here
  ],
  plugins: [],
  localization: {
    locales: [
        'en',
        'es',
    ],
    defaultLocale: 'en',
    fallback: true,
  },
});

.env

MONGODB_URI=mongodb://user:pass@127.0.0.1:27017/db?authSource=admin
PAYLOAD_SECRET=MYSECRET
PAYLOAD_CONFIG_PATH=src/payload.config.js
PAYLOAD_PUBLIC_SERVER_URL=http://localhost:1336
PAYLOAD_PUBLIC_PORT=1336
PAYLOAD_PUBLIC_DEBUG=FALSE
NODE_ENV=PRODUCTION
  • default discord avatar
    gonzam88
    last year

    Thanks @jmikrut I finally found the error on my side. Given I was using a reverse proxy I thought the Payload serverUrl still had to be localhost:1337. For anyone reading, given the way I configured my payload.config.js, this is the .env that finally worked for me, pay attention to PAYLOAD_PUBLIC_SERVER_URL and PAYLOAD_PUBLIC_PORT

    Production Deploy .env

    MONGODB_URI=mongodb://user:pass@127.0.0.1:27017/db?authSource=admin
    PAYLOAD_SECRET=MYSECRET
    PAYLOAD_CONFIG_PATH=src/payload.config.js
    PAYLOAD_PUBLIC_SERVER_URL=https://mysite.com
    PAYLOAD_PUBLIC_PORT=1336
    PAYLOAD_PUBLIC_DEBUG=FALSE
    NODE_ENV=PRODUCTION
    

    Local development .env

    MONGODB_URI=mongodb://user:pass@127.0.0.1:27017/db?authSource=admin
    PAYLOAD_SECRET=MYSECRET
    PAYLOAD_CONFIG_PATH=src/payload.config.js
    PAYLOAD_PUBLIC_SERVER_URL=https://localhost:3000
    PAYLOAD_PUBLIC_PORT=3000
    PAYLOAD_PUBLIC_DEBUG=TRUE
    
    1 reply
  • discord user avatar
    jmikrut
    Payload Team
    last year

    Ah yep. Good call. This makes perfect sense. Happy to hear that you solved it and thank you for following up!

  • discord user avatar
    jmikrut
    Payload Team
    last year

    Hey @gonzam88 — we've seen similar issues before and it is related to your auth cookie(s) being rejected.

    Do you have any cookie options configured on your admins collection? Generally this issue is due to you having a problem with specifying secure cookies, but not using HTTPS, or trying to use cross-domain cookies which are now rejected in newer versions of popular browsers.

    A way to check why a cookie is being rejected is to open the Inspector in Chrome, go to the Network tab, and then log in to the admin UI. You should try and find the login network POST request. Click that request, and see if there is a little yellow "warning" symbol next to the Set-Cookie header of that request.

    Here is a screenshot of a working login request within our demo admin panel:

    Screen Shot 2022-06-16 at 10 15 46 AM

  • default discord avatar
    gonzam88
    last year

    Hi @jmikrut thanks for the reply. My cookie looks fine 🍪 yet req is still undefined. Any other place to look? Thanks in advanced.
    Screen Shot 2022-06-17 at 1 06 28 PM

    2 replies
    discord user avatar
    jmikrut
    Payload Team
    last year

    OK. Can you send the full error message that you're seeing regarding req being undefined? We've never seen that before..

    Also, I'm not sure if it's related (don't see how it would be) but generally we just have one location block within our nginx reverse proxy configs, like this:

    server {
            server_name website.com;
    
            location / {
                    proxy_pass http://localhost:1337;
                    proxy_http_version 1.1;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection 'upgrade';
                    proxy_set_header Host $host;
                    proxy_cache_bypass $http_upgrade;
                    proxy_set_header X-Forwarded-For $remote_addr;
            }
    }
    
    default discord avatar
    gonzam88
    last year

    fyi I tried this configuration just in case but got the same result

  • default discord avatar
    gonzam88
    last year

    The thing with the nginx configuration is I need my static vue site running on / and then payload on both /admin and /api. I could be wrong, or maybe there's a better approach way but this worked for me before with other CMSs.

    There's actually no error displayed, I just can't edit docs with my admin users unless my access is
    update: ({ req: { user } }) => { return true },

    If I try a rule where only admin users can edit like the following I get the typical You are not allowed to perform this action

    const adminsAndEditors =  async ({ req: { user } }) => {
      if (!user) return false // return false to deny a user
      if(user.collection == 'admins') return true // every admin can edit
    }
    

    Creating - Section - Douob - Google Chrome 6_17_2022 4_15_32 PM

    Let me know if there's any other info I can provide.

    1 reply
    default discord avatar
    gonzam88
    last year
    [19:15:30] ERROR (payload): Forbidden: You are not allowed to perform this action.
        at new ExtendableError (/var/www/testing-douob-server-payload/node_modules/payload/src/errors/APIError.ts:26:11)
        at new APIError (/var/www/testing-douob-server-payload/node_modules/payload/src/errors/APIError.ts:43:5)
        at new Forbidden (/var/www/testing-douob-server-payload/node_modules/payload/src/errors/Forbidden.ts:6:5)
        at executeAccess (/var/www/testing-douob-server-payload/node_modules/payload/src/auth/executeAccess.ts:9:43)
        at processTicksAndRejections (internal/process/task_queues.js:95:5)
        at Payload.create (/var/www/testing-douob-server-payload/node_modules/payload/src/collections/operations/create.ts:74:5)
        at Payload.create (/var/www/testing-douob-server-payload/node_modules/payload/src/collections/requestHandlers/create.ts:14:17)
    
Open the post
Continue the discussion in GitHub
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.