Bird
Raised Fist0
Astroframework~20 mins

Protected routes and middleware in Astro - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Astro Middleware Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What happens when a user accesses a protected Astro route without authentication?

Consider an Astro project with a middleware that checks user authentication before allowing access to a protected route.

What is the expected behavior if a user tries to access /dashboard without being logged in?

Astro
export async function onRequest({ request, redirect }) {
  const isAuthenticated = Boolean(request.headers.get('cookie')?.includes('session'));
  if (!isAuthenticated) {
    return redirect('/login');
  }
  return new Response('Welcome to your dashboard');
}
AThe server returns a 404 Not Found error.
BThe user sees the dashboard content without restrictions.
CThe user is redirected to the /login page.
DThe user receives a 500 Internal Server Error.
Attempts:
2 left
💡 Hint

Think about what the middleware does when authentication fails.

📝 Syntax
intermediate
2:00remaining
Identify the syntax error in this Astro middleware for protected routes

Review the following Astro middleware code intended to protect a route by checking a token in cookies.

Which option correctly identifies the syntax error?

Astro
export async function onRequest({ request, redirect }) {
  const token = request.headers.get('cookie').match(/token=([^;]+)/)[1];
  if (!token) {
    return redirect('/login');
  }
  return new Response('Access granted');
}
AThe <code>redirect</code> function is used incorrectly; it should be <code>return redirect('/login', 401)</code>.
BCalling <code>match</code> on <code>null</code> if no cookie header exists causes a runtime error.
CThe regular expression syntax is invalid and causes a syntax error.
DThe function must be named <code>middleware</code> instead of <code>onRequest</code>.
Attempts:
2 left
💡 Hint

Consider what happens if the cookie header is missing.

❓ state_output
advanced
2:00remaining
What is the response status code when middleware blocks access?

Given this Astro middleware protecting a route, what HTTP status code will the client receive when not authenticated?

Astro
export async function onRequest({ request, redirect }) {
  const isLoggedIn = request.headers.get('cookie')?.includes('auth=true');
  if (!isLoggedIn) {
    return redirect('/login');
  }
  return new Response('Protected content');
}
A302 Found (redirect to /login)
B401 Unauthorized
C403 Forbidden
D200 OK
Attempts:
2 left
💡 Hint

What does the redirect function do by default?

🔧 Debug
advanced
2:00remaining
Why does this Astro middleware fail to protect the route?

Examine this middleware code. It is supposed to block access if the user is not authenticated, but it allows access anyway.

What is the cause?

Astro
export async function onRequest({ request, redirect }) {
  const cookie = request.headers.get('cookie');
  if (cookie && cookie.includes('auth=true')) {
    return new Response('Access granted');
  }
  // Missing return here
  return redirect('/login');
}
AThe redirect is called but not returned, so the function continues and returns undefined, allowing access.
BThe cookie check is incorrect; it should check for 'auth=false' instead.
CThe middleware function must be synchronous, but this is async.
DThe redirect function requires a second argument for status code.
Attempts:
2 left
💡 Hint

What happens if you call a function but do not return its result in middleware?

🧠 Conceptual
expert
3:00remaining
How does Astro middleware differ from traditional Express middleware in protecting routes?

Choose the statement that best describes a key difference between Astro's middleware approach for protected routes and Express.js middleware.

AAstro middleware only works client-side, while Express middleware runs server-side.
BAstro middleware requires explicit calls to next(), whereas Express middleware automatically proceeds after execution.
CExpress middleware cannot modify response headers, but Astro middleware can.
DAstro middleware runs on the edge before rendering and returns a response or redirect, while Express middleware uses next() to pass control.
Attempts:
2 left
💡 Hint

Think about how Astro middleware handles requests compared to Express.

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