Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Req.user null presumably due to cross-site request?

default discord avatar
ingrid741last year
9

So my payload app is serving multiple frontends using rewrites to mask payload's domain name with their own, ie

https://oversoul.no

where the payload app is running at

https://multitenant-1.payloadcms.app

. So when I'm making a request from the admin panel like so,


      const url = `${process.env['PAYLOAD_PUBLIC_SERVER_URL']}/data/api/email-history/verifyTransporter`
      const res = await fetch(url, {
        method: 'GET',
        credentials: 'include',
        headers: {
          "Content-Type": "application/json",
        },
      })

the request

origin

is

https://oversoul.no

, whereas the request URL resolves to

https://multitenant-1.payloadcms.app/data/api/email-history/verifyTransporter

. I think this is causing an issue with the auth cookie because when I push everything to Cloud,

req.user

is null on the request. Once I added

credentials: 'include'

to the request

req.user

was populated - but only on localhost. On Cloud

req.user

resolves to null, which leads me to think the cookie is blocked.



Collection

users

is good on cross-domain cookies:


  auth: {
    useAPIKey: true,
    tokenExpiration: 28800, // 8 hours
     cookies: {
       sameSite: 'none', // med denne på må secure være true, ellers settes ikke cookien
       secure: true, // med denne på nekter Chrome å sette cookien på http, må være https (unntatt localhost)
       // domain: '.localhost', // brukes for å tillate deling av cookies på tvers av subdomener i frontend 
     },
  },
...

Setting

csrf

(and

cors

) to no avail in

payload-config

:


  cors: [ 'https://multitenant-1.payloadcms.app', 'https://oversoul.no' ],
  csrf: [ 'https://multitenant-1.payloadcms.app', 'https://oversoul.no' ],

There is a preflight request which returns 200 so I don't think CORS is the issue.



Checking dev tools the

payload-token

cookie is there and its domain is

oversoul.no

, it is

strict

and

sameSite: 'none'

.



Any ideas welcome what is going on here 🙏 Thanks!



Turns out

req.user

is lost on localhost as well, but only if

csrf

is set with something. If given an empty array or dropped,

req.user

is populated. If given

['localhost']

or

['http://localhost']

it is not populated. On Cloud we're in an actual cross-site context and so dropping it doesn't work

  • default discord avatar
    sourabpramaniklast year

    you also got to provide the port number if running locally

  • default discord avatar
    ingrid741last year

    Thanks! Adding port number, it works locally with the

    csrf

    property set in config.



    Why is it not working on Cloud though, even if I add admin panel origin precisely to csrf? I'm logdumping

    payload.config.csrf

    and verifying it is set with the requesting origin exactly.



    @967118574445547650

    This could not possibly by a caching issue right...?

  • default discord avatar
    sourabpramaniklast year

    To send the cookies to a different domain you have add the domain in the cookie options.


    e.g. domain: 'oversoul.no'

  • discord user avatar
    denolfe
    last year

    As

    @681934949128994835

    mentioned, you'll need to add the actual domain that cloud deploys on to your cookies and csrf

  • default discord avatar
    ingrid741last year

    That makes sense but it's still not working, unfortunately.



    Current setup:



    * Added any & all relevant domains (without protocol) to csrf config like so:

    csrf: ["localhost:3000","multitenant-1.payloadcms.app","oversoul.no","oscar-floor.vercel.app","localhost:3002"]



    * Added Cloud default domain to cookies config:



    export const Users: CollectionConfig = {
      slug: 'users',
      auth: {
        useAPIKey: true,
        tokenExpiration: 28800, // 8 hours
        cookies: {
          sameSite: 'none',
          secure: true,
          domain: '.payloadcms.app',
        },
      },
    ...


    Also tried cookie domains

    multitenant-1.payloadcms.app

    ,

    .multitenant-1.payloadcms.app

    ,

    .oversoul.no
  • default discord avatar
    sourabpramaniklast year

    CSRF and CORS must have all the domains with the exact protocols



    Which domain is pointing to your hosted payload app?

  • default discord avatar
    ingrid741last year
    https://multitenant-1.payloadcms.app

    Could be the one and only combination I haven’t tried yet (csrf with protocols and correct cookie setting), trying that now



    New development: If I login from

    payloadcms.app

    I can login and user is set 🥳 If I try from a login page that is masked with FE domain, login doesn't work (page just reloads, no cookie set).



    The issue now is that cookie domain can take just one domain, right? Meaning I won't be able to authenticate users from several frontends using HTTP cookie, unless there is some workaround?



    So far my FEs have been fetching data using API keys associated with tenant admins, which is super. But as I'm about to implement FE auth I'm going to need auth by login cookie, as well as this case here where I'm trying to authenticate a logged-in admin in the admin panel from a masked domain 🙏



    Any ideas?



    Can't be the only one running into this



    This is unexpected. Tried removing cookie domain setting and it seems to work. I can log in from masked domain, and requests are able to use the cookie. User it set.



    It's basically setting only CSRF w/protocol, which I did try a couple times 🤷



    Thank you for the input Elliot and Sourab.



    Ahh nevermind. The issue at hand was solved 🙂 Excuse me

  • default discord avatar
    fedes5626last year

    hey

    @735059082293149777

    I think I'm having the same issue, I want to use my staging login cookie in my local frontend enviroment.


    So my payload admin is on stg.example.com


    And my local frontend is on localhost:3000



    my payload.config.ts



    cors: [
      'http://localhost:3000',
    ],
    csrf: [
      'http://localhost:3000',
    ]


    also my Users config has



      auth: {
        useAPIKey: true,
        cookies: {
          sameSite: 'None',
          secure: false,
          domain: 'localhost',
        },
      },


    but I also tried without it as I understand you didn't need that after all?



    BTW when running cms on localhost:3001 and frontend in localhost:3000 it works fine

  • default discord avatar
    zapata.ethlast year

    try checking the nextjs config and add these



    import { withPayload } from '@payloadcms/next/withPayload'
    
    /** @type {import('next').NextConfig} */
    const nextConfig = {
      output: 'standalone',
      async headers() {
        return [
          {
            source: '/api/:path*',
            headers: [
              { 
                key: 'Access-Control-Allow-Origin', 
                value: `${process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : 'http://localhost:3000'}`
              }
            ]
          },
        ]
      },
    }
    
    export default withPayload(nextConfig, { devBundleServerPackages: false })
Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.