Hone logo
Hone
Problems

Secure Your Routes: Implementing Vue Navigation Guards

In modern web applications, controlling access to certain routes is crucial for security and user experience. This challenge focuses on implementing Vue.js navigation guards to conditionally allow or deny access to specific routes based on user authentication status. You will leverage TypeScript to define and apply these guards effectively.

Problem Description

Your task is to implement global and per-route navigation guards in a Vue.js application using TypeScript. These guards will protect routes that require user authentication.

What needs to be achieved:

  • Implement a global navigation guard (beforeEach) that checks if a user is authenticated before allowing navigation to any protected route.
  • Implement a per-route navigation guard (beforeEnter) for a specific route to demonstrate alternative guarding strategies.
  • Simulate user authentication status.
  • Handle redirection when a user is not authenticated and attempts to access a protected route.

Key Requirements:

  • Use Vue Router v4 (Composition API is preferred).
  • All code should be written in TypeScript.
  • A isAuthenticated boolean variable should be used to simulate the user's login status.
  • The /dashboard route should be protected, requiring authentication.
  • The /login route should be accessible to everyone.
  • If an unauthenticated user tries to access /dashboard, they should be redirected to /login and a message should be displayed (e.g., in the console or a simple alert) indicating why.
  • If an authenticated user tries to access /login, they should be redirected to /dashboard.

Expected Behavior:

  1. When an unauthenticated user navigates to /dashboard, they are redirected to /login.
  2. When an authenticated user navigates to /dashboard, they can access the route.
  3. When any user navigates to /login, they can access the route.
  4. When an authenticated user navigates to /login, they are redirected to /dashboard.

Edge Cases:

  • Consider the initial load of the application. If the user is unauthenticated and the initial route is /dashboard, they should be redirected to /login.
  • Ensure that the guards don't create infinite redirection loops (e.g., guarding /login and redirecting to /dashboard, and then guarding /dashboard and redirecting to /login without proper conditions).

Examples

Let's assume a simplified Vue Router setup and a mock authentication service.

Scenario 1: Unauthenticated User Tries to Access Protected Route

  • Input (Simulated State): isAuthenticated = false
  • Navigation Attempt: User navigates to /dashboard
  • Output (Expected Router Behavior):
    • User is redirected to /login.
    • Console logs a message: "Authentication required. Redirecting to login."
  • Explanation: The beforeEach guard intercepts the navigation to /dashboard. Since isAuthenticated is false, the guard prevents navigation and initiates a redirect to /login.

Scenario 2: Authenticated User Accesses Protected Route

  • Input (Simulated State): isAuthenticated = true
  • Navigation Attempt: User navigates to /dashboard
  • Output (Expected Router Behavior):
    • User successfully navigates to /dashboard.
  • Explanation: The beforeEach guard intercepts the navigation. Since isAuthenticated is true, the guard allows navigation to proceed to /dashboard.

Scenario 3: Authenticated User Tries to Access Login Route

  • Input (Simulated State): isAuthenticated = true
  • Navigation Attempt: User navigates to /login
  • Output (Expected Router Behavior):
    • User is redirected to /dashboard.
  • Explanation: The per-route beforeEnter guard for /login detects that the user is authenticated and redirects them to /dashboard, preventing them from seeing the login page when they are already logged in.

Constraints

  • Vue Router v4 must be used.
  • TypeScript must be used for all implementations.
  • The solution should be adaptable to a typical Vue.js project structure (e.g., router/index.ts, views/Login.vue, views/Dashboard.vue).
  • For the purpose of this challenge, you don't need to implement actual UI components, but your code should be structured as if they exist. Focus on the router configuration and guard logic.
  • The isAuthenticated variable can be a simple boolean within your router setup for this exercise.

Notes

  • Consider using router.push() or router.replace() for redirects. Understand the difference and choose appropriately.
  • Remember to pass next() or to/from objects correctly in your guard functions.
  • Think about how to manage the authentication state in a real application (e.g., using a Pinia store, Vuex, or a service). For this challenge, a simple boolean is sufficient.
  • The goal is to understand the mechanics of beforeEach and beforeEnter guards and how they contribute to secure routing.
Loading editor...
typescript