Bird
Raised Fist0
Astroframework~30 mins

Protected routes and middleware in Astro - Mini Project: Build & Apply

Choose your learning style10 modes available
Protected Routes and Middleware in Astro
📖 Scenario: You are building a simple website with Astro that has some pages only accessible to logged-in users. To protect these pages, you will create middleware that checks if a user is authenticated before allowing access.
🎯 Goal: Build a protected route in Astro using middleware that checks for a user session. If the user is not logged in, redirect them to the login page.
📋 What You'll Learn
Create a mock user session object
Add a configuration variable for the login page URL
Write middleware to check user authentication
Apply the middleware to protect a route and redirect unauthenticated users
💡 Why This Matters
🌍 Real World
Websites often need to protect certain pages so only logged-in users can see them. Middleware helps check user status before showing content.
💼 Career
Understanding protected routes and middleware is essential for building secure web applications and is a common task for frontend and full-stack developers.
Progress0 / 4 steps
1
Create a mock user session object
Create a variable called userSession that is an object with a property isLoggedIn set to false.
Astro
Hint

Think of userSession as a simple object that tells if the user is logged in or not.

2
Add a configuration variable for the login page URL
Create a constant called loginPage and set it to the string "/login".
Astro
Hint

This variable will hold the URL where users are sent if they are not logged in.

3
Write middleware to check user authentication
Write an async function called authMiddleware that takes context as a parameter. Inside, check if userSession.isLoggedIn is false. If so, return a redirect response to loginPage. Otherwise, return context.next().
Astro
Hint

This middleware will stop users who are not logged in and send them to the login page.

4
Apply the middleware to protect a route
In the same file, export a constant called middleware as an array containing authMiddleware. This will apply the middleware to the route.
Astro
Hint

Exporting middleware as an array with your function tells Astro to run it on this route.

Practice

(1/5)
1. What is the main purpose of middleware in Astro when protecting routes?
easy
A. To check user access before loading a page
B. To style the page content dynamically
C. To fetch data after the page loads
D. To optimize images on the page

Solution

  1. Step 1: Understand middleware role

    Middleware runs before a page loads to perform checks or actions.
  2. Step 2: Identify middleware use in protected routes

    It checks if a user has permission to access certain pages before showing them.
  3. Final Answer:

    To check user access before loading a page -> Option A
  4. Quick Check:

    Middleware checks access = D [OK]
Hint: Middleware runs first to check access before page loads [OK]
Common Mistakes:
  • Thinking middleware styles pages
  • Assuming middleware fetches data after load
  • Confusing middleware with image optimization
2. Which syntax correctly defines a middleware matcher for protecting all routes under /dashboard in Astro?
easy
A. export const matcher = '/dashboard/*';
B. export const matcher = ['/dashboard/*'];
C. export const matcher = ['/dashboard'];
D. export const matcher = '/dashboard';

Solution

  1. Step 1: Recall matcher syntax

    Matcher must be an array of strings specifying route patterns.
  2. Step 2: Match all routes under /dashboard

    Using '/dashboard/*' inside an array matches all subpaths.
  3. Final Answer:

    export const matcher = ['/dashboard/*']; -> Option B
  4. Quick Check:

    Matcher is array with pattern string = A [OK]
Hint: Matcher must be an array of route strings [OK]
Common Mistakes:
  • Using string instead of array for matcher
  • Missing wildcard * to match subroutes
  • Using exact path without wildcard for nested routes
3. Given this middleware code in Astro, what happens when a user visits /profile without a valid token?
export const matcher = ['/profile'];

export async function middleware({ request, redirect }) {
  const token = request.headers.get('authorization');
  if (!token) {
    return redirect('/login');
  }
  return;
}
medium
A. Middleware throws an error
B. User sees the /profile page
C. User is redirected to /login
D. User is redirected to /home

Solution

  1. Step 1: Check token presence

    The middleware checks if the 'authorization' header exists in the request.
  2. Step 2: Redirect if no token

    If token is missing, middleware redirects user to '/login'.
  3. Final Answer:

    User is redirected to /login -> Option C
  4. Quick Check:

    No token means redirect to /login = A [OK]
Hint: No token triggers redirect to login [OK]
Common Mistakes:
  • Assuming user sees page without token
  • Expecting error instead of redirect
  • Redirecting to wrong path
4. Identify the error in this Astro middleware code meant to protect /admin routes:
export const matcher = '/admin/*';

export function middleware({ request, redirect }) {
  const user = request.headers.get('user');
  if (user !== 'admin') {
    redirect('/not-authorized');
  }
}
medium
A. request.headers.get does not exist
B. redirect should be called with await
C. middleware must be async function
D. matcher should be an array, not a string

Solution

  1. Step 1: Check matcher syntax

    Matcher must be an array of strings, not a single string.
  2. Step 2: Confirm redirect usage

    Redirect can be called synchronously; no await needed here.
  3. Final Answer:

    matcher should be an array, not a string -> Option D
  4. Quick Check:

    Matcher array required = C [OK]
Hint: Matcher must always be an array even for one route [OK]
Common Mistakes:
  • Using string instead of array for matcher
  • Thinking redirect needs await
  • Confusing request.headers API
5. You want to protect both /dashboard and /settings routes using middleware in Astro. Which matcher setup correctly protects both paths and their subpaths?
hard
A. export const matcher = ['/dashboard/*', '/settings/*'];
B. export const matcher = ['/dashboard', '/settings'];
C. export const matcher = ['/dashboard*', '/settings*'];
D. export const matcher = ['/dashboard/**', '/settings/**'];

Solution

  1. Step 1: Understand wildcard usage

    '/*' matches all subpaths under a route, ensuring protection of nested pages.
  2. Step 2: Verify matcher array format

    Matcher must be an array of strings with correct wildcard patterns.
  3. Final Answer:

    export const matcher = ['/dashboard/*', '/settings/*']; -> Option A
  4. Quick Check:

    Array with '/*' wildcard protects subpaths = B [OK]
Hint: Use '/*' wildcard in array to protect all subroutes [OK]
Common Mistakes:
  • Omitting wildcard to protect subpaths
  • Using incorrect wildcard like '**'
  • Using string instead of array for matcher
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard