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.

How to get authenticated user in custom express routes?

default discord avatar
wojciechkrol2 years ago
1 3

I'm building custom endpoints to extend some collections and I wonder how to get the authenticated user from an express route?

See an example:

app.get("/api/invoices/:id/print", async function (req, res) {
  // check permissions before print
  ...
});

Let's say I want to download a pdf for a selected invoice and I want to make sure that the user is authenticated and has correct privileges. I wanted to use Local API payload but I don't see any option to get a user. Is it possible?

  • Selected Answer
    discord user avatar
    jmikrut
    2 years ago

    Hey @wojciechkrol — this is totally possible!

    Check this page:
    https://payloadcms.com/docs/authentication/using-middleware

    We've got an Express middleware that allows you to re-use Payload's built-in auth easily. Should be exactly what you need. Note that this will only expose req.user for you to do what you want, but you still have to make sure to still enforce your own access control there.

    One other thing you can do is also pass your user from your own Express endpoint into the Payload Local API, so it's used seamlessly.

    Bam!

    1 reply
  • default discord avatar
    wojciechkrol2 years ago

    Thank you! My fault, I overlooked this page in docs. You saved my time!

  • default discord avatar
    GeorgeyB2 years ago

    To add to @jmikrut's answer - if invoices is a collection, you also have the option of providing a custom endpoint with the endpoints collection configuration property where the Payload middleware is bound for you:

    const Invoices = {
        slug: 'invoices',
        endpoints: [
            {
                path: '/:id/print',
                method: 'get',
                handler: ({ user }) => {
                    // Handle the request...    
                }
            },
        ]
    }
    
    1 reply
    default discord avatar
    wojciechkrol2 years ago

    Whoa! Good to know :) You should update documentation to let people know about this feature.

    Thank you!

  • discord user avatar
    jacobsfletch
    2 years ago

    I've run into a similar issue, but it requires a different strategy than described here.

    I need to figure out how to authenticate Payload from my custom Express route which is hit by a Stripe webhook. I need to use the local Payload api to handle these events, but the problem is that even if I use Payload authentication middleware, the source of the webhook is unauthenticated. Stripe only allows basic auth headers the url (https://user/:pass@) which is likely not what we want.

    It’s almost like we need to login manually after Stripe webhooks hit the Payload server, then proceed to use the local api

    Here’s an example:

    app.post('/stripe/webhooks', [
      payload.authenticate,
      express.raw({ type: 'application/json' }),
      (req: express.Request, res: express.Response): void => {
        // THIS WILL ALWAYS HIT, BECAUSE THE STRIPE WEBHOOK ORIGIN IS UNAUTHENTICATED
        if (req && !req.user) {
          return res.status(403).json({ message: 'You must be logged in to do this.' });
        }
    
        const stripeSignature = req.headers['stripe-signature'];
    
        let event: Stripe.Event;
    
        try {
          event = stripe.webhooks.constructEvent(req.body, stripeSignature, process.env.STRIPE_WEBHOOKS_ENDPOINT_SECRET);
          // CAN WE AUTHENTICATE MANUALLY HERE?!
          handleWebhooks(event, stripe, {});
        } catch (err) {
          console.error(`Webhook Error: ${err.message}`);
          res.status(400);
          return;
        }
    
        console.log('✅ Success:', event.id);
        res.json({ received: true });
      },
    ]);

    Since Stripe can authenticate their own webhook by reading the signature in the header, it seems like we can safely log in using credentials from an .env.

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

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