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?
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!
Thank you! My fault, I overlooked this page in docs. You saved my time!
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...
}
},
]
}
Whoa! Good to know :) You should update documentation to let people know about this feature.
Thank you!
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
Discord
online
Get help straight from the Payload team with an Enterprise License.