VueJS基于角色的路由认证:登录后按角色跳转路由
Hey there! Let's walk through how to set up that role-based redirect after login—this is a super common pattern, and it's pretty straightforward once you map out the steps. Since your example uses router.push, I'll start with Vue Router (the most likely stack here) and throw in a React Router example too, just in case you're working with that.
Step 1: Capture & Store the User Role After Login
First, when your login API call succeeds, you'll get the userType (student/admin/dataEntry) back. You need to store this somewhere accessible—either in local/session storage for persistence, or a state management tool like Pinia (Vue) or Zustand/Redux (React).
Vue Example (Login Handler)
async function handleLogin(formData) { try { // Call your login API endpoint const response = await fetch('/api/login', { method: 'POST', body: JSON.stringify(formData), headers: { 'Content-Type': 'application/json' } }); const loginData = await response.json(); const { userType } = loginData; // Store the role (use Pinia/Vuex instead if you're using state management) localStorage.setItem('currentUserRole', userType); // Now handle the redirect based on role switch(userType) { case 'student': router.push('/student'); break; case 'admin': router.push('/admin'); break; case 'dataEntry': router.push('/dataEntry'); break; default: // Fallback for unknown roles—adjust this to your needs router.push('/'); console.warn(`Unknown user role: ${userType}`); } } catch (error) { // Handle login failures (show error message to user, etc.) console.error('Login failed:', error); alert('Login unsuccessful—please check your credentials.'); } }
Step 2: Add Route Guards (Optional but Critical for Security)
To make sure users can't access routes they don't have permission for (like a student trying to hit /admin), add route guards to enforce role-based access control.
Vue Global Route Guard Example
Add this to your router/index.js file:
router.beforeEach((to, from, next) => { const userRole = localStorage.getItem('currentUserRole'); // Map each route to allowed roles const allowedRoles = { '/student': ['student'], '/admin': ['admin'], '/dataEntry': ['dataEntry'] }; // Check if the target route requires a specific role if (allowedRoles[to.path]) { if (!userRole) { // No role stored? Redirect to login page next('/login'); } else if (!allowedRoles[to.path].includes(userRole)) { // User doesn't have permission—redirect to unauthorized page or home next('/unauthorized'); } else { // All good, let them through next(); } } else { // Public routes (like login, home) don't need checks next(); } });
React Router Alternative
If you're using React with react-router-dom, here's how you'd implement the same logic:
Login Handler (Using useNavigate)
import { useNavigate } from 'react-router-dom'; function LoginPage() { const navigate = useNavigate(); const handleLogin = async (formData) => { try { const response = await fetch('/api/login', { method: 'POST', body: JSON.stringify(formData), headers: { 'Content-Type': 'application/json' } }); const loginData = await response.json(); const { userType } = loginData; localStorage.setItem('currentUserRole', userType); // Redirect logic let targetPath = '/'; switch(userType) { case 'student': targetPath = '/student'; break; case 'admin': targetPath = '/admin'; break; case 'dataEntry': targetPath = '/dataEntry'; break; } navigate(targetPath); } catch (error) { console.error('Login failed:', error); alert('Login unsuccessful—please check your credentials.'); } }; // Rest of your login component code... }
Role-Based Route Component
Create a PrivateRoute component to wrap your protected routes:
import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; function PrivateRoute({ children, allowedRoles }) { const userRole = localStorage.getItem('currentUserRole'); const navigate = useNavigate(); useEffect(() => { if (!userRole) { navigate('/login'); } else if (!allowedRoles.includes(userRole)) { navigate('/unauthorized'); } }, [userRole, allowedRoles, navigate]); return userRole && allowedRoles.includes(userRole) ? children : null; } // Use it in your route config: <Routes> <Route path="/login" element={<LoginPage />} /> <Route path="/student" element={ <PrivateRoute allowedRoles={['student']}> <StudentDashboard /> </PrivateRoute> } /> <Route path="/admin" element={ <PrivateRoute allowedRoles={['admin']}> <AdminDashboard /> </PrivateRoute> } /> {/* Other routes */} </Routes>
A quick note: Using local storage is fine for persistence, but if you need more secure state management (especially for sensitive apps), opt for a state management library instead—it keeps the role in memory and reduces exposure to XSS risks.
内容的提问来源于stack exchange,提问作者margherita pizza

