Permissions framework based on VUE (Element UI) + SSM + Shiro.

Digest it, understand it, digest it!


The introduction

voice

Now the Java world, a variety of resources are very rich, I have to say, from distributed, servitization, ORM, and then front-end control, permissions and so on, there is a saying on the Internet, language framework iteration is too fast, I can not learn to move, it is better to go back to move bricks, but it is so hot, bricks are hot. The program is easy, just a little cold.


Two world puzzles for programmers

Repeat the wheel

Language framework iteration fast, yes, there are dozens of, for simple high-level language it is though several popular so, language is one of repetition, from the perspective on the role of language to express, is in order to operate the computer, I think the prospect of the future computer language integration could be language, of course, this is a very long way, believe the creator of some languages, At the beginning, I was not satisfied with a certain language, so I changed it, but in fact, most of it was repetitive. In this respect, I have deep experience. At the beginning, JUST to better learn the principle of MVC framework, I thought the best way to learn it was to rewrite it. It just implemented the basic mapping from the page to the processing side, as well as processing the return, which is actually relatively simple to think about, especially the principle, is better processing and mapping of the page and the controller, of course, perfect rewrite, I didn’t do that, there are a lot of popular open source MVC framework, Another is a simple reconstruction of ORM framework Hulichao_framework under the yBatis, what is achieved, is the mutual mapping between the database and Java program, at the same time the convention fixed method at the beginning of the can not write SQL statements, want to explain what the problem? First, I am repeating the wheel, Of course in the learning process, I harvest very big, even if the existing framework cannot meet some functionality, but if reclaimed its price is higher, also do not recommend, secondly, the process of learning is the first principle, interface, and the process of commented code, just like the previous framework from the outset, I want to achieve the main function of understand, then refer to the main principle, Design interface, finally write code implementation, is not difficult to carry.

Communication problems

Second question not only involves the human actually, also involves the machine and human relations, product manager, said, I want to do a digger to stir-fry, excavators, according to the best optimization route, just like the unmanned vehicle, equipment at the same time, can according to the owner’s taste recommend cuisine, both to maintain its original function, and can be used as a private little helper, In the most elegant way to make the most delicious food, is not cooking, for many people is not complex, open an excavator believe that don’t need too much knowledge, and make recommendation algorithm, please some related experts, should also is not very big problem, but the whole process together is difficult, the Internet is like this, All kinds of real problems in life are realized with the thinking of the Internet, so what is the problem? That is communication, communication between various professionals, the interaction between designers’ ideas and implementers’ ideas, and the interaction between machines and people. It sounds like a joke, or the plot of a science fiction movie, but well, it is. For programmers, communication with colleagues and product managers, what the requirements are and how they can be realized depends on the fit degree of the whole team.

advice

Understand principle useful, but don’t repeat the wheel, don’t repeat the wheel, don’t repeat the wheels, would rather go to dead simple to find a circle to find the wheels of the basic right, also don’t write to pack to force their wheels, otherwise will be very uncomfortable, as for communication, have to say is a refractory, so come out to an interface design, program to an interface, This way is more natural than fat boy happy water.




To the chase

As the front end separation project boom, front end each are big the framework, before and after the end of the communication part also became a problem, the server before rendering pages generated to the front, front end can be two servers now, some technical migration, the permissions on the part of the framework of the design idea, draw lessons from the idea of the front-end Daniel, also the traditional back-end design scheme of the topic, do a bridge, Before and after the end of the separation of authority design, code for reference only, ideas for reference only, I believe that excellent you write your own code, with their own ideas will be more appropriate, convenient. Finally, it has unified response structure, front-background data flow mechanism (mutual conversion mechanism between HTTP messages and Java objects), unified exception handling mechanism, parameter verification mechanism, Cors cross-domain request mechanism and authentication mechanism front-end design: Using Vue’s Element UI, it should be easy for front-end designers to understand the source code. Back end design: Shiro + SSM + Redis stores JWT interaction mode: Front end stores JWT and carries it when accessing back end, which is the only interactive authentication mode. Preliminary work: VUE templates, routes, resources, roles and users were designed in line with the requirements. The corresponding relationships among them could also be reflected in the data table

Written in the book before

In practical applications, one of them requires users to simply register and log in, and the other is to authorize them, with session management and encryption attached, so Shiro framework is born. The trend of separating the front end from the back end makes shiro more practical to be applied to the front end. At present, front-end frameworks like Vue are also very popular. At the same time, we were in touch with VUE, so to meet the requirements, we abstracted the permissions framework based on the complete separation of the front and back ends. In addition, it is generally believed that permissions can only be done by the back end, but what about the case where the front and back ends are separated? Wouldn’t that be very pointless? Moreover, there is relatively no mainstream scheme for vUE’s permission control in the industry. Baidu has little information in this respect, which is basically scattered. Front-end address: github.com/hulichao/zh… Back-end address: github.com/hulichao/zh…

Design ideas

The basic idea is to use Vuex for state control and Vue Router for routing, so that permissions can be directly mapped to components, and one can only access one component, without having to add permissions to each component, and importantly, single sign-on. So start by writing a generic framework (or at least a generic idea) that can be modular and pluggable. The problem with non-dynamic routing is that the Vue instance can only be initialized after the permission is obtained, so the landing page must be separated from the SPA and made into a separate page. The user login/logout operation needs to jump between two urls, which makes the experience slightly worse.

Another approach is to directly instantiate the application with all routes. When the user logs in and gets the permission, the user can hide the override menu through element operation. At this time, the user can also manually enter the address to access the override page, so it is necessary to add beforeEach hooks to the route to restrict the access. And instantiation, registering all routes, also causes the front end to load redundant routing components. This system uses the initial route registration home page and login page, and gets the permission after getting the token, and then instantiates the Vue instance. The routing codes are as follows:

const router = new Router({
  routes: [{path: '/login'.name: "login".component: LoginView,
      meta: { requiresAuth: false }
    },{
      path: '/index'.redirect: '/'.meta: { requiresAuth: true}}}); generateIndexRouter();// Verify the token before jumping
router.beforeEach((to, from, next) = > {
  let token = sessionStorage.getItem('token')
  if(to.path === '/') {
    if(! token) { next({path: '/login'.query: { redirect: to.fullPath }
      })
      return}}if(to.meta.requiresAuth) {
		if(token) {
			next()
		} else {
			next({
				path: '/login'.query: { redirect: to.fullPath }
			})
		}
	} else {
		next()
	}
});

router.afterEach((to, from) = > {
  // Set the breadcrumbs
  let breadCrumbItems = []
  let homePageCrumb = {
    title: 'home'.to: '/'
  }
  breadCrumbItems.push(homePageCrumb)
  if(to.meta.nameFullPath) {
    let fullPathSplit = to.meta.nameFullPath.split('/')
    fullPathSplit.forEach(( item, index ) = > {
      let routerBreadCrumb = {
        title: item,
        to: (index == fullPathSplit.length - 1 ? to.path : ' ')
      }
      breadCrumbItems.push(routerBreadCrumb)
    });
  }
  // Update to state
  router.app.$store.dispatch('setBreadcurmbItems', breadCrumbItems)
})

// Generate the home route
function generateIndexRouter() {
  if(! sessionStorage.routers) {return
  }
  let indexRouter = {
    path: "/".name: "/".component: resolve= > require(['@/views/home/index'], resolve),
    children: [
      ...generateChildRouters()
    ]
  }
  router.addRoutes([indexRouter])
}

// Generate nested routines (child routing)
function generateChildRouters() {
  let routers = JSON.parse(sessionStorage.routers)
  let childRouters = []
  for(let router of routers) {
    if(router.code ! =null) {
      let routerProps = JSON.parse(router.properties)
      let childRouter = {
        path: router.url,
        name: router.code,
        component: resolve= > require(['@/views/' + router.code + '/index'], resolve),
        meta: { routerId: router.id, requiresAuth: routerProps.meta.requiresAuth, nameFullPath: routerProps.nameFullPath }
      }
      childRouters.push(childRouter)
    }
  }
  return childRouters
}

export default router;

Copy the code

Data format conventions for the front and back ends

One class inherits hashMap in such a way that it can return arbitrary data. Common data is code, MSG, data. If there are pages, there will be additional pages. Data.msg.state (code).token + pagination type data such as:

"data": {
    "list": null,
    "pagebar": {
      "page": 1,
      "total": 2."limit": 10}},"msg": "error"."state": 0."is_redirect": true."redirect_url": "http://qq.com"."token": null
Copy the code

In consideration of later extensibility, this project uses the first class, which implements the commonly used failure and success status codes and their responses. The class name is designed as Result, located under ZHcc-common, and is generally wrapped in ResponseEntity to return.

Data interface conventions of the front and back ends

Corresponding HTTP protocol the get/put/post/delete method, the back-end permissions are: read / : the update / : : create/delete

case "get":
    permissionString += ":read";
    break;
case "put":
    permissionString += ":update";
    break;
case "post":
    permissionString += ":create";
    break;
case "delete":
    permissionString += ":delete";
Copy the code

Verify the part

Using com. Baidu. Unbiz. Fluentvalidator. ValidationError rather than hibernateValidator ease the pressure on server-side programming, etc. Validates directly in the controller and returns it encapsulated in the fail method of Result.

Permission design

The control of permissions can be divided into four categories, mainly based on the RBAC principle. Routing, resource, role, user routing level and component level are controllable

Process design

1. Permission design 2. Exception design 3. Dictionary and other interface design 4

instructions

Vue. Js is the best tutorial, vue. Js is the best tutorial, vue. If you don’t believe me, we’ll see!

How does it work?

A demo, a how-to guide, a list of apis, and a test.

  1. Demo how to use
  • Git Clone NPM run dev NPM init then NPM install and then NPM run dev or NPM run build you know the difference.
  • Git clone backend address clone Change the database path, run SQL to import the database, and run it on the server. Of course, this is the development phase. In production, you may need an Nginx server to deploy the front-end code.
  1. Beginner’s guide, for such a good you, should not need it.
  2. API and testing will be refined later. Keep an eye on this document for real-time information.

Donation

If you like it, go for coffee. If you don’t like a cup or half a cup, fork and star a little.

reference

  • Reference 1: VUE permissions front-end design
  • Reference 2: CSDN edu.csdn.net/course/play…
  • Reference 3: Open Source frameworks gitee.com/zhocuhengli…
  • Reference 4: VUE official website
  • Reference 5: VUE Permission control github.com/OneWayTech/…

Deliberate practice

Clear, from learning itself is not difficult to read a book, for example, learn to use a framework, and so on, even if zero basis to skilled, the amount of time and energy are not many, and the skills of stack is accumulated bit by bit, the great god, and that appear to proudly behind involve “dirty”, why can’t you, Because you want to quickly, you want to master all the skills overnight, so now all kinds of quick, such as 21 days to learn from the library to run away books are very popular, in fact, there is no shortcut, only a warning: self-discipline can change life, growth lies in persistence and accumulation. The lesson from deliberate practice is that to learn, we as programmers, in whatever form, remember to program -> feedback -> fix -> rearrange learning. More personal blog http://hulichao.top, I have wine, you want to come?