Hey! I need to have different guards for auth, like in Laravel (php). For example: I have site, when I need an authenticate user, and I have an admin panel, but in admin I need new middleware of auth to check permissions to see admin panel. May be package has this functionality already, but I didn't find it.
Please, give me some example or something to help me solve this problem. Thanks!
Hello @weijinnx
The auth-module still does not check the user's permissions, this can be done by a middleware.
I do not have a flexible solution to contribute, but maybe this middleware I developed helps you out.
My check-permissions.js
import {isEmpty, find, kebabCase, isString, isArray, castArray, map, some, includes, intersection} from 'lodash';
// export default function({app, store, route}) {
export default async function({app, store, route, redirect}) {
// Check auth cookie and get user data
await store.dispatch('auth/fetch');
// If it is authenticated
if (store.getters['auth/loggedIn']) {
let user = store.state['auth']['user'];
if (!user) {
return;
}
let meta = getRouteMeta(route);
let roleNames = user.roles.map(item => kebabCase(item.name));
if (meta.auth) {
let only = meta.auth.only;
let except = meta.auth.except;
let allow = true;
if (only) {
// Set default to Array
if (isString(only) || isArray(only)) {
only = castArray(only);
// Change properties for kebabCase
only = map(only, item => {
return kebabCase(item);
});
// If has user the roles, can access the route
allow = intersection(only, roleNames).length > 0;
}
} else if (except) {
// Set default to Array
if (isString(except) || isArray(except)) {
except = castArray(except);
// Change properties for kebabCase
except = map(except, item => {
return kebabCase(item);
});
// If has not user the role, or has other role authorized, can access the route
allow = some(roleNames, item => {
return !includes(except, item);
});
}
}
if (!allow) {
if (meta.auth.redirectTo) {
let desiredRoute = app.router.resolve(meta.auth.redirectTo);
redirect(desiredRoute.route.path);
} else {
redirect('/');
}
}
}
} else {
redirect('/');
}
};
/**
* Get the metadata of the route or your closest relative.
*
* @param {Object} route
* @returns {Object}
*/
function getRouteMeta(route) {
if (!isEmpty(route.meta)) {
return route.meta;
}
let routeFound = find(route.matched, item => {
return item.name === route.name;
});
if (!routeFound) {
return {};
}
if (!routeFound.parent) {
return {};
}
return getRouteMeta(routeFound.parent);
}
In route.js:
{
path: '/',
name: 'dashboard',
component: DashboardPage,
meta: {
auth: {
except: 'Admin', // or ['Admin'] your role names
// only: 'Admin', // or ['Admin'] your role names
redirectTo: {
name: 'home', // Same arguments as VueRouter
},
},
},
},
Would be good to have an implementation of this using the same pattern as used for turning auth off, e.g. at the component level. Should be fairly easy to knock together and would work for people still using Nuxt's auto route handling.
For example:
export default {
auth: {
roles: {
except: [...],
only: [...]
}
}
}
Permissioning and authorization are out of scope of this module, which only handles authentication.
Most helpful comment
Would be good to have an implementation of this using the same pattern as used for turning auth off, e.g. at the component level. Should be fairly easy to knock together and would work for people still using Nuxt's auto route handling.
For example: