BayBreezy / protect-server-api-nuxt3

Learn how to protect your Nuxt 3 API endpoints
https://protect-server-api-nuxt3.netlify.app
37 stars 1 forks source link

[Enhancement] - Protect event handlers with `onRequest` #82

Open ChrisGV04 opened 2 months ago

ChrisGV04 commented 2 months ago

Hi!

I just wanted to suggest an alternative way to protecting the API event handlers on a more maintainable manner.

With the current implementation, you will need to add every API path you want to protect to the guard middleware, which may be a bit tedious and you won't know just by looking at the event handler if it requires authentication or not, since you need to go to the guard file and check if it's included in the list of protected paths.

The way I like to implement it is using H3's defineEventHandler object syntax and adding the guard to the onRequest option. That way, I can immediately know it the handler is protected and very easily choose which guards I want to apply to it. This also makes it very flexible since you can add more than one "pre-handler" to them.

Here's an example:

/** server/api/users/index.post.ts */

export default defineEventHandler({
  onRequest: [onlyAuth], // Add as many pre-handlers as you need
  handler: (event) => {
    // You can be sure that this handler will only get called if `onlyAuth` succeeded
  }
})
/** server/utils/auth.ts */

import type { EventHandler } from 'h3';

export const onlyAuth: EventHandler = (event) => {
  await requireUserSession(event);
}

People familiar with Fastify will recognize this pattern to be very similar to preHandler or middleware from Express.

BayBreezy commented 2 months ago

Hey! Thank you for the suggestion. It's always good to see a better way of doing this in the dev world.

I will check out the recommendation in the h3 docs. I am not so deep into h3 as I should be.

ChrisGV04 commented 2 months ago

Sure thing!

The H3 docs for the object syntax are practically non-existent, that's why it's not as known.

https://h3.unjs.io/guide/event-handler#object-syntax

I have tested it for several months in production and it has been working exactly as intended.