Access Control
For frontend applications, "access control" refers to whether pages are accessible and whether page elements are visible.
Setup
- Install the plugin
$ npm add @winner-fed/plugin-access -D$ yarn add @winner-fed/plugin-access -D$ pnpm add @winner-fed/plugin-access -D$ bun add @winner-fed/plugin-access -D- Enable the plugin in the
.winrcconfiguration file
import { defineConfig } from 'win';
export default defineConfig({
plugins: ['@winner-fed/plugin-access'],
routes: [{
path: '/',
name: 'Home',
component: 'index',
routes: [
{
path: 'admin',
name: 'Admin',
component: '@/components/admin'
},
{
path: 'normal',
name: 'Normal',
component: '@/components/normal'
}
]
}],
/**
* @name Access Control Plugin
* @doc https://winjs-dev.github.io/winjs-docs/plugins/access.html
*/
access: {
roles: {
admin: ['/admin'],
normal: ['/normal']
}
}
});Introduction
In this plugin design, one page permission corresponds to one route. For example, when accessing the '/admin' route, if the current role doesn't have permission for this route, the component will not be rendered.
export default {
access: {
roles: {
admin: ['/admin'],
normal: ['/normal']
}
}
};Usage example:
<template>
<Access :id="accessId">Only visible to Admin</Access>
<div v-access="accessId">Only visible to Admin</div>
</template>
<script setup lang="ts">
const accessId = '/admin';
</script>Note
We uniformly refer to pages and page elements as resources, and use resource IDs to identify and distinguish them:
- The resource ID of a page defaults to the page's route
path. For example, the routepathof pagepages/a.vueis/a. When the page accesses/a, the current page will be rendered, and/ais the page'saccessId. - Page elements' resource IDs have no default value and need to be customized. :::
Matching Rules
Exact Matching
The default matching rule for resources is exact matching. For example, if page pages/a.vue corresponds to route path /a, then /a is the page's resource ID. If we set:
access.setAccess(['/a']);Since the permission list contains /a, it indicates having permission for this page.
Fuzzy Matching
Page @id.vue will be mapped to dynamic route /:id. There are two ways to match this page:
- access.setAccess(['/:id'])
- access.setAccess(['/*'])
The second is fuzzy matching, where * represents any path. For example, if role admin needs full permissions:
export default {
access: {
roles: {
admin: ['*']
}
}
};Compile-time Configuration
When executing win dev or win build, runtime code is generated through this configuration. Configure in the .winrc.js configuration file:
export default {
access: {
roles: {
admin: ['/', '/admin', '/normal'],
},
},
};roles
Type:
Record<string, []>;Default:
{}Details:
Predefined role list.
keyis the role ID, andvalueis the resource list corresponding to the role ID.
Runtime Configuration
Configure in app.js
unAccessHandler
Type:
FunctionDefault:
nullDetails: When entering a route, if the page corresponding to the route doesn't belong to the visible resource list, entry will be paused and the
unAccessHandlerfunction will be called.Parameters
- router: Router instance created by createRouter
- to: Route being navigated to
- from: Route being navigated away from
- next: next function
Example:
import { access as accessApi } from 'winjs';
export const access = {
unAccessHandler ({ to, next }) {
const accesssIds = accessApi.getAccess();
if (to.path === '/404') {
accessApi.setAccess(accesssIds.concat(['/404']));
return next('/404');
}
if (!accesssIds.includes('/403')) {
accessApi.setAccess(accesssIds.concat(['/403']));
}
next('/403');
},
};noFoundHandler
- Type:
Function - Default:
null - Details: When entering a route, if the page corresponding to the route doesn't exist, the
noFoundHandlerfunction will be called. - Parameters
- router: Router instance created by createRouter
- to: Route being navigated to
- from: Route being navigated away from
- next: next function
Example:
import { access as accessApi } from 'winjs';
export const access = {
noFoundHandler ({ next }) {
const accesssIds = accessApi.getAccess();
if (!accesssIds.includes('/404')) {
accessApi.setAccess(accesssIds.concat(['/404']));
}
next('/404');
},
};ignoreAccess
- Type:
Array<string> - Default:
null - Details: Configure pages that should ignore access control validation.
Example:
export const access = {
ignoreAccess: ['/login'],
};API
WinJS uses custom directives, specifically the v-access directive, passing in the object returned by useAccess to control component rendering.
Plugin APIs are exported through winjs:
import { access } from 'winjs';access.hasAccess
- Type:
( accessId: string | number ) => Promise\<boolean\> - Details: Determine whether a resource is visible.
- Parameters:
- accessId: Resource ID
- Returns: Whether access is granted
access.isDataReady
- Type:
() => boolean - Details: Permissions can be set using asynchronous data.
isDataReadyis used to determine whether asynchronous data has finished loading. - Parameters: null
- Returns: Boolean
import { access } from 'winjs';
console.log(access.isDataReady());access.setRole
- Type:
Function - Details: Set the current role.
- Parameters:
- roleId: Role ID, has two types:
- String: Corresponds to the
keyin therolesconfiguration object. - Promise: The result of Promise resolve should correspond to the
keyin therolesconfiguration object.
- String: Corresponds to the
import { access } from 'winjs';
access.setRole('admin');access.getRole
- Type:
Function - Details: Get the current role.
import { access } from 'winjs';
access.getRole();access.setAccess
- Type:
Function - Details: Set the current access permissions.
- Parameters:
- accessIds: Array of resource IDs, has two types:
- Array: Array items correspond to the
keyin therolesconfiguration object. - Promise: The result of Promise resolve should be
Array<accessId>.
- Array: Array items correspond to the
import { access } from 'winjs';
access.setAccess(['/a', '/b', '/c']);access.getAccess
- Type:
Function - Details: Return the current list of visible resources.
- Parameters: null
import { access } from 'winjs';
access.getAccess();useAccess
- Type: Composition function
- Details: Determine whether a resource is visible.
- Parameters:
- accessId: Resource ID
- Returns:
ref
<template>
<div v-if="accessOnepicess">accessOnepicess</div>
</template>
<script>
import { useAccess } from 'winjs';
export default {
setup () {
const accessOnepicess = useAccess('/onepiece1');
return {
accessOnepicess,
};
},
};
</script>v-access
Pass accessId into the v-access directive. When accessId has permission, the DOM will be displayed; when there's no permission, the DOM will be hidden.
<template>
<div v-access="accessId">accessOnepicess</div>
</template>
<script>
export default {
setup () {
return {
accessId: 'accessOnepicess',
};
},
};
</script>Access Component
Pass accessId into the Access component. When accessId has permission, this component will be rendered; when there's no permission, this component will be hidden.
<template>
<access :id="accessId"> accessOnepicess</access>
</template>
<script>
export default {
setup () {
return {
accessId: 'accessOnepicess',
};
},
};
</script>