#Executing middleware in only some pages

16 messages · Page 1 of 1 (latest)

gray juniper
#

In the docs, it shows middleware being used for all pages using src/middleware.js. If I want to use middleware, say for protecting only some pages after a login, what would be the best way to do it?

frail tapirBOT
#

Hi @gray juniper. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To use middleware for protecting only specific pages after a login, you can create a middleware function and use the matcher property in the config object to specify the routes you want the middleware to run on. Here's an example from the Vercel Middleware section (https://docs.astro.build/en/guides/integrations-guide/vercel#vercel-middleware):

export const config = {
  // Only run the middleware on the admin route
  matcher: '/admin',
};

export default function middleware(request) {
  const url = new URL(request.url);
  // You can retrieve IP location or cookies here.
  if (url.pathname === "/admin") {
    url.pathname = "/"
  }
  return Response.redirect(url);
}

In this example, the middleware is only applied to the /admin route. You can modify the matcher property to match the routes you want to protect after a login.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

Astro Documentation

Learn how to use the @astrojs/vercel SSR adapter to deploy your Astro project.

#

@gray juniper kapa.ai is still learning and improving, please let us how it did by reacting below

gray juniper
#

@frail tapir I’m not using the Vercel middleware. I’m using the native Astro middleware solution

frail tapirBOT
#

Let me check the knowledge base for you. One moment! :books:

#

I apologize for the confusion. In the case of native Astro middleware, you can conditionally apply the middleware based on the requested route. Here's an example:

// src/middleware.ts
export async function onRequest({ request, locals }, next) {
  // Check the requested route
  const url = new URL(request.url);
  const protectedRoutes = ['/protected-page-1', '/protected-page-2'];

  if (protectedRoutes.includes(url.pathname)) {
    // Apply middleware logic for protected routes
    // For example, check for authentication
    const sessionId = request.headers.get("cookie");
    const user = await getUser(sessionId);
    if (!user) {
      return new Response(null, { status: 405 });
    }
    locals.user = user;
  }

  return next();
}

In this example, the middleware checks if the requested route is in the protectedRoutes array. If it is, the middleware logic for protected routes is applied, such as checking for authentication. If the route is not in the protectedRoutes array, the middleware will simply call next() and continue without applying any additional logic.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@gray juniper kapa.ai is still learning and improving, please let us how it did by reacting below

gray juniper
#

@frail tapir Will the middleware run in nested pages? e.g. /protected-page-1/nested-page

frail tapirBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Yes, the middleware will run on nested pages as well. To apply the middleware to nested pages, you can modify the condition in the middleware to check if the requested route starts with any of the protected routes. Here's an example:

// src/middleware.ts
export async function onRequest({ request, locals }, next) {
  // Check the requested route
  const url = new URL(request.url);
  const protectedRoutes = ['/protected-page-1', '/protected-page-2'];

  // Check if the requested route starts with any of the protected routes
  const isProtectedRoute = protectedRoutes.some(route => url.pathname.startsWith(route));

  if (isProtectedRoute) {
    // Apply middleware logic for protected routes
    // For example, check for authentication
    const sessionId = request.headers.get("cookie");
    const user = await getUser(sessionId);
    if (!user) {
      return new Response(null, { status: 405 });
    }
    locals.user = user;
  }

  return next();
}

In this example, the isProtectedRoute variable checks if the requested route starts with any of the protected routes. If it does, the middleware logic for protected routes is applied. This will work for nested pages like /protected-page-1/nested-page.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@gray juniper kapa.ai is still learning and improving, please let us how it did by reacting below

eager sequoia
# gray juniper <@1072591948499664996> Will the middleware run in nested pages? e.g. `/protected...

here I confirm the Kapa approach, in short

  • no, you cannot run Astro middleware on only some pages
  • but, you can filter what you want and skip the rest
    Middleware is for concepts like auth and cases where you need a place where 'everything' goes through.
    Now of course it makes sense to have middleware on route basis and then you can chose either top level or specific route, its just not like that in Astro, maybe in a future upgrade...
gray juniper
#

Or maybe a blacklist instead of a whitelist for where I don’t want middleware to run

eager sequoia
#

for auth, it is important that there is no exception, you check all, then let whitelist go, basically would not need auth for them. Whitelist is safer as you might forget to add a new page to the blacklist. So that the Middleware is aware of all pages is here ok I think.