Recipe Request: Complex Route Redirection
tim-soft opened this issue · 1 comments
Let's say I have an app with many user roles and many routes. Every route must be protected from unauthorized users and every route must be protected based on a list of permitted user roles.
If I'm understanding the docs correctly, a route is always evaluated starting from the root '/' and cascades down until the desired route is found.
What would be a good strategy for protecting a really large amount of routes for a large amount of reasons? My current plan is to add a function into every route which checks the user. This method feels a little tedious with a more complex app. Is there a more pragmatic pattern with Universal Router?
You can use middleware route like so (jsfiddle playground):
import UniversalRouter from 'universal-router';
import createBrowserHistory from 'history/createBrowserHistory';
const router = new UniversalRouter([
{ path: '', action: () => ({ content: 'Home Page' }) },
{ path: '/login', action: () => ({ content: 'Login Page' }) },
{ // middleware route
path: '', // or '/admin' if you need to protect only admin routes
action(context) {
if (!context.user) {
return { redirect: '/login', from: context.pathname };
}
if (context.user.role !== 'Admin') {
return { content: 'Access denied!' };
}
return context.next(); // go to child routes
},
children: [
{ path: '/protected', action: () => ({ content: 'Protected Page' }) },
// ... (a lot of routes)
],
},
]);
const history = createBrowserHistory();
function render(location) {
router.resolve({
pathname: location.pathname,
user: null, // { name: 'Jhon', role: 'Guest' },
}).then(page => {
if (page.redirect) {
history.push(page.redirect, { from: page.from });
} else {
document.body.innerHTML = page.content;
}
});
}
history.listen(render);
render(history.location); // initial render
or any other technique from redirects recipe