Hone logo
Hone
Problems

Vue Router Navigation Guards: Building a Protected Route

This challenge focuses on implementing route guards in a Vue.js application using TypeScript. Navigation guards are crucial for controlling access to routes, performing actions before navigation, or redirecting users based on certain conditions. You will create a simple authentication system to protect specific routes.

Problem Description

You need to build a basic authentication mechanism for a Vue application using Vue Router's navigation guards. Specifically, you will implement a beforeEach guard to check if a user is authenticated before allowing them to access a "dashboard" route. If the user is not authenticated, they should be redirected to a "login" route.

Key Requirements:

  1. Vue Router Setup: You should have a basic Vue Router instance configured with at least two routes: / (home), /login, and /dashboard.
  2. Authentication State: Simulate an authentication state. This can be a simple boolean variable or a more sophisticated object representing a user. For this challenge, a global boolean variable isAuthenticated will suffice.
  3. beforeEach Navigation Guard: Implement a global beforeEach navigation guard.
  4. Route Protection: The /dashboard route should be protected.
  5. Redirection Logic:
    • If a user tries to navigate to /dashboard and isAuthenticated is false, they should be redirected to /login.
    • If a user tries to navigate to /login and isAuthenticated is true, they should be redirected to /dashboard (as they are already logged in).
    • All other navigation should proceed as normal.
  6. TypeScript: All code should be written in TypeScript.

Expected Behavior:

  • Navigating to / should work without authentication.
  • Navigating to /login when not authenticated should display the login page.
  • Navigating to /dashboard when not authenticated should redirect to /login.
  • Navigating to /login when already authenticated should redirect to /dashboard.
  • Navigating to /dashboard when authenticated should display the dashboard.

Edge Cases to Consider:

  • What happens if the user is already on the /login page and attempts to navigate to it again? (Should not cause an infinite loop).
  • What happens if the user is already on the /dashboard page and attempts to navigate to it again?

Examples

Example 1: User navigates to the protected dashboard route while unauthenticated.

// Assume isAuthenticated is false globally

// User attempts to navigate to '/dashboard'
router.push('/dashboard');

// Expected Behavior:
// The beforeEach guard intercepts the navigation.
// Since isAuthenticated is false, the user is redirected to '/login'.
// The router.push('/dashboard') effectively becomes router.push('/login').

Example 2: User navigates to the login route while already authenticated.

// Assume isAuthenticated is true globally

// User attempts to navigate to '/login'
router.push('/login');

// Expected Behavior:
// The beforeEach guard intercepts the navigation.
// Since isAuthenticated is true, the user is redirected to '/dashboard'.
// The router.push('/login') effectively becomes router.push('/dashboard').

Example 3: User navigates to the dashboard route while authenticated.

// Assume isAuthenticated is true globally

// User attempts to navigate to '/dashboard'
router.push('/dashboard');

// Expected Behavior:
// The beforeEach guard intercepts the navigation.
// Since isAuthenticated is true, the navigation to '/dashboard' is allowed to proceed.

Constraints

  • Your solution should be implemented within a Vue.js 3 project using the Composition API and Vue Router 4.
  • The simulated authentication state (isAuthenticated) should be a simple boolean variable, managed globally or passed appropriately.
  • The solution should be performant and not introduce unnecessary overhead for typical navigation.

Notes

  • You'll need to set up a basic Vue project and install vue-router.
  • Think about how to manage the isAuthenticated state. A simple global variable is sufficient for this challenge, but in a real application, you'd likely use a state management solution like Pinia or Vuex.
  • The next() function in beforeEach is crucial for controlling navigation. Remember its different argument types (boolean, string, object).
  • Consider how to handle the initial load of the application and its route guards.
Loading editor...
typescript