Secure Route Access with Vue Navigation Guards (TypeScript)
Navigation guards in Vue.js provide a powerful mechanism to control access to routes based on various conditions, such as user authentication status or specific roles. This challenge will guide you in implementing navigation guards to ensure that only authorized users can access certain parts of your application, enhancing security and user experience. You'll be building guards for both route entry and route leaving, handling different scenarios gracefully.
Problem Description
You are tasked with creating navigation guards for a Vue.js application using TypeScript. The application has three routes: /, /admin, and /profile. The /admin route should only be accessible to authenticated users (users who have a token in local storage). The /profile route should only be accessible if the user has a role of 'user' in local storage. The / route should redirect unauthenticated users to /login (which doesn't exist in this challenge, so just redirect to /). Additionally, when a user navigates away from the /admin route while authenticated, a confirmation dialog should appear asking if they are sure they want to leave. If they confirm, navigation should proceed; otherwise, navigation should be cancelled.
Key Requirements:
- Authentication Guard: Prevent access to
/adminfor unauthenticated users. - Role-Based Guard: Prevent access to
/profilefor users without the 'user' role. - Before Route Leave Guard: Display a confirmation dialog when leaving
/adminwhile authenticated. - Redirection: Redirect unauthenticated users to
/from any route other than/. - TypeScript: The solution must be written in TypeScript.
Expected Behavior:
- When an unauthenticated user attempts to access
/admin, they should be redirected to/. - When a user without the 'user' role attempts to access
/profile, they should be redirected to/. - When an authenticated user navigates away from
/admin, a confirmation dialog should appear. - If the user confirms the dialog, navigation should proceed.
- If the user cancels the dialog, navigation should be prevented.
- All other routes should be accessible without restrictions (though unauthenticated users will be redirected from routes other than
/).
Edge Cases to Consider:
- What happens if
tokenorroleare missing from local storage? - How should the confirmation dialog be implemented (you can use a simple
confirm()function for this challenge)? - How to handle potential race conditions if the authentication status changes during navigation? (For simplicity, assume this is not a major concern in this challenge).
Examples
Example 1:
Input: User is unauthenticated, attempts to navigate to /admin
Output: User is redirected to /
Explanation: The authentication guard prevents access to /admin for unauthenticated users.
Example 2:
Input: User is authenticated, has role 'admin', navigates away from /admin
Output: A confirmation dialog appears asking "Are you sure you want to leave the admin page?". If the user clicks "OK", navigation proceeds. If the user clicks "Cancel", navigation is cancelled.
Explanation: The beforeRouteLeave guard triggers the confirmation dialog.
Example 3:
Input: User is authenticated, has role 'user', attempts to navigate to /profile
Output: User is able to access /profile
Explanation: The role-based guard allows access to /profile for users with the 'user' role.
Constraints
- The solution must be implemented using Vue Router's navigation guard API.
- The authentication status and role information must be retrieved from local storage.
- The confirmation dialog can be implemented using the built-in
confirm()function. - The solution should be concise and readable.
- The application should use Vue 3 and TypeScript.
Notes
- Consider using a separate function for each guard to improve code organization and reusability.
- Think about how to handle the case where the user is already on the
/adminroute and their authentication status changes. - This challenge focuses on the core logic of navigation guards. Styling and complex dialog implementations are not required.
- You'll need to set up a basic Vue 3 project with TypeScript and Vue Router to implement this challenge. Assume this setup is already complete. Focus on the guard implementation itself.
- The
tokenandrolekeys in local storage are strings.