I’ve been learning about Vue3 stacks recently, including CompositionAPI, TypeScript, Vite, and Element Plus, Element UI’s version of Vue3.

So you want to write a simple RBAC user permission system using Vue3.

I used to use MySQL as a relational database. Recently, WHEN I was learning Kong Gateway, I came into contact with Postgres as a relational database and saw a sentence saying: “MySQL is by far the most widely used database, but Postgres is by far the most advanced.”

Of course, this is the most advanced Postgres open-source organization bills itself. But Postgres does seem to me to be a lot more fun to use than MySQL, at least when it comes to data type support.

I often use Json or Array fields, and Postgres supports Json fields very well. Of course, MySQL 5.7 will also support Json fields, but in terms of performance and usage, I still feel Postgres is better. I don’t know much about MySQL myself.

Well, without further ado, let’s actually look at the project.

This project will not over-encapsulate either the front end or the back end. It will not encapsulate what should not be encapsulated. It will not over-encapsulate the code in order to install X, so as to reduce the time cost of looking at the code.

Demo site: fdevops.com:8088

Github:github.com/lanyulei/sk… , if you feel ok, please don’t be stingy with the beating of your fingertips, gently click on a star.

Casbin Permission control

In this system, Casbin is used as the permission management dependency of the interface, and RBAC is used to manage the interface. Multi-role binding of users is supported.

The Casbin model file is as follows:

[request_definition]
r = sub, obj, act
 
[policy_definition]
p = sub, obj, act
 
[role_definition]
g = _, _
 
[policy_effect]
e = some(where (p.eft == allow))
 
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
Copy the code

In fact, it is the RBAC model content provided on the official website of Casbin. If you need to use custom functions, you can refer to the official website to add them.

Casbin.org/docs/zh-CN/…

Simple encapsulation of Casbin Gin middleware.

package permission import ( "sky/pkg/conn" "sky/pkg/logger" "sky/pkg/tools/response" "time" "github.com/casbin/casbin/v2" gormAdapter "github.com/casbin/gorm-adapter/v3" "github.com/gin-gonic/gin" "github.com/spf13/viper" ) var Enforcer *casbin.SyncedEnforcer func CasbinSetup() *casbin.SyncedEnforcer { var ( err error adapter *gormAdapter.Adapter ) adapter, err = gormAdapter.NewAdapterByDBWithCustomTable(conn.Orm, nil, viper.GetString("casbin.tableName")) if err ! Logger. Fatal(" Failed to create casbin GORm adapter, error: %v", err) } Enforcer, err = casbin.NewSyncedEnforcer(viper.GetString("casbin.rbacModel"), adapter) if err ! Fatal(" Casbin enforcer failed, error: %v", err)} err = enforcer.loadPolicy () if err! Fatal(" Failed to load policy from database, error: %v", err)} // Timing synchronization policy if viper.getbool (" casbin.istiming ") {// How long is the interval for synchronizing permission policy, unit: SEC Enforcer. StartAutoLoadPolicy (time. The Second * time. The Duration (9) get int (" casbin. IntervalTime ")))} return Enforcer} Func CheckPermMiddleware() gin.HandlerFunc {return func(c *gin.Context) {obj := c.equest.url.path // Act Sub := c.getString ("username") isAdmin := C.getbool ("isAdmin") if isAdmin {c.next ()} else { If ok, _ := Enforcer.Enforce(sub, obj, act); ok { c.Next() } else { response.Error(c, nil, response.NoPermissionError) c.Abort() } } } }Copy the code

Menu permissions

Menu You can control the permissions of menu ids accessible to roles to enable multiple menu ids.

The routing example is as follows:

{path: '/user', name: 'user', Component: () => import('/@/views/user/list.vue'), meta: {title:' user list ', auth: ['system:user:list'] // This is the route id. Only the role is associated with this ID can be accessed. }},Copy the code

To verify whether the current user has permission, the user’s permission identification list will be stored in Vuex. The current system defines the concept of super administrator for users. Therefore, when a program is a super administrator, the system directly permits the application.

export function setFilterRoute(chil: any) { let filterRoute: any = []; chil.forEach((route: any) => { if (route.meta.auth) { route.meta.auth.forEach((metaAuth: any) => { store.state.userInfos.userInfos.authPageList.forEach((auth: Any) = > {/ / if it is the super administrator, directly through the if (store. State. UserInfos) userInfos) is_admin | | metaAuth = = = auth) filterRoute. Push ({... route }); }); }); }}); return filterRoute; }Copy the code

Project presentations

Menu management, menu creation, page element creation and menu binding API interface.

Binding API interfaces to menus facilitates interface permission management.

Page element management, including but not limited to buttons.

Interface management, all back-end interfaces that need to be verified by Casbin.

Authorize roles.

Screenshot content, is only a part of the function, detailed content, you can visit the demo site to view.

If you have any questions, leave a comment here at www.fdevops.com.