All Projects → JiriChara → Vue Kindergarten

JiriChara / Vue Kindergarten

Licence: mit
Modular security for Vue, Vuex, Vue-Router and Nuxt

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Vue Kindergarten

Vue Soundcloud
🎧 A SoundCloud client built with Vue and Nuxt
Stars: ✭ 141 (-53.47%)
Mutual labels:  nuxt, vuex, vuejs2, vue-router
Vuemmerce
👉 Responsive ecommerce template 🛒 built with Vue.js and Nuxt.js
Stars: ✭ 223 (-26.4%)
Mutual labels:  nuxt, vuex, vuejs2, vue-router
Vue Project
基于vue-cli构建的财务后台管理系统(vue2+vuex+axios+vue-router+element-ui+echarts+websocket+vue-i18n)
Stars: ✭ 301 (-0.66%)
Mutual labels:  vuex, vuejs2, vue-router
Nuxt Elm
基于nuxt2+vue构建的全栈开源项目
Stars: ✭ 304 (+0.33%)
Mutual labels:  nuxt, vuex, vue-router
Hackernews
HackerNews clone built with Nuxt.js
Stars: ✭ 758 (+150.17%)
Mutual labels:  nuxt, vuex, vue-router
Vue Axios Github
Vue 全家桶 + axios 前端实现登录拦截、登出、拦截器等功能
Stars: ✭ 2,622 (+765.35%)
Mutual labels:  vuex, vuejs2, vue-router
Vue Cnode
🔥Vue.js打造一个开源的CNode社区。CNode by Vue.js
Stars: ✭ 249 (-17.82%)
Mutual labels:  vuex, vuejs2, vue-router
Roastandbrew
Updated content available! We learned a lot since we originally wrote this article. We now have this updated for Laravel 8, Vue, and NuxtJS 👉 https://srvrsi.de/book
Stars: ✭ 300 (-0.99%)
Mutual labels:  vuex, vuejs2, vue-router
Vue Objccn
🔥 Use Vue.js to develop a cross-platform full stack application / 用 Vue.js 开发的跨三端应用
Stars: ✭ 1,993 (+557.76%)
Mutual labels:  vuex, vuejs2, vue-router
Nuxt.js
The Intuitive Vue(2) Framework
Stars: ✭ 38,986 (+12766.67%)
Mutual labels:  nuxt, vuex, vue-router
Laravel Vuejs.com
Laravel and VueJs Blog, using Laravel nova, GraphQL, NuxtJs, Apollo and ...more
Stars: ✭ 54 (-82.18%)
Mutual labels:  nuxt, vuex, vue-router
Copilot
Responsive Bootstrap 3 Admin Template based on AdminLTE with vue.js
Stars: ✭ 2,698 (+790.43%)
Mutual labels:  vuex, vuejs2, vue-router
Lvyou
🎒Vue.js 初步进阶案例,路由懒加载,进入页面前登录判断,返回导航判断,RestAPI接口使用,组件封装,Vuex状态封装,keep-alive页面缓存等功能
Stars: ✭ 195 (-35.64%)
Mutual labels:  vuex, vuejs2, vue-router
Vue Home
🏠 A simple project(Vue Community SPA) which bases on vue+vue-cli+vue-router+axios+ scss.
Stars: ✭ 256 (-15.51%)
Mutual labels:  vuex, vuejs2, vue-router
Vue2 Demo
Vue 基于 Genesis + TS + Vuex 实现的 SSR demo
Stars: ✭ 2,072 (+583.83%)
Mutual labels:  vuex, vuejs2, vue-router
Vuecnodejs
⚽️🎉Vue初/中级项目,CnodeJS社区重构。( a junior project of Vue.js, rewrite cnodejs.org ) 预览(DEMO):
Stars: ✭ 705 (+132.67%)
Mutual labels:  nuxt, vuex, vue-router
Gpk admin
✨ GeekPark Content Management System
Stars: ✭ 150 (-50.5%)
Mutual labels:  vuex, vuejs2, vue-router
Vuetify Todo Pwa
✔️ A simple Todo PWA built with Vue CLI 3 + Vuex + Vuetify.
Stars: ✭ 160 (-47.19%)
Mutual labels:  vuex, vuejs2, vue-router
Nuxt Ssr Demo
✨ 高仿掘金,整合 vue + nuxt + axios + vuex + vue-router (nuxt 自带 vuex 和 vue-router),一个基于 Nuxt 的服务器端渲染 Demo
Stars: ✭ 856 (+182.51%)
Mutual labels:  nuxt, vuex, vue-router
Vue Cheatsheet
Modified version of the official VueMastery cheatsheet
Stars: ✭ 188 (-37.95%)
Mutual labels:  nuxt, vuex, vue-router

vue-kindergarten

Build Status codecov NPM Version NPM Dowloads Dependency Status

Introduction

vue-kindergarten is a plugin for VueJS 2.0 that integrates kindergarten into your VueJS applications. It helps you to authorize your components, routes and the rest of your application in very modular way. If you are not familiar with kindergarten yet, I highly recommend you to check out the README first.

Installation

yarn add vue-kindergarten
# or
npm install vue-kindergarten

And you can register the plugin like this:

import Vue from 'vue';
import VueKindergarten from 'vue-kindergarten';

import App from './App';
import router from './router';
import store from './store';

Vue.use(VueKindergarten, {
  // Getter of your current user.
  // If you use vuex, then store will be passed
  child: (store) => {
    return store.state.user;
    // or
    // return decode(localStorage.getItem('jwt'));
    // or your very own logic..
  }
});

new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App },
});

Usage

First we need to define our perimeters. Perimeter is a module that represents some part of your applications or a business domain. It defines rules that has to be respected and can additionally expose some methods that you can use in your application.

import { createPerimeter } from 'vue-kindergarten';

createPerimeter({
  purpose: 'article',

  can: {
    read: () => true

    // only admin or moderator can update articles
    update(article) {
      return this.isAdmin() || (this.isCreator(article) && this.isModerator());
    },

    // if user can update articles then she can also destroy them
    destroy(article) {
      return this.isAllowed('update', article);
    }
  },

  secretNotes(article) {
    this.guard('update', article);

    return article.secretNotes;
  },

  isAdmin() {
    return this.child.role === 'admin';
  },

  isModerator() {
    return this.child.role === 'moderator';
  },

  isCreator(article) {
    return this.child.id === article.author.id;
  },

  expose: [
    'secretNotes'
  ]
});
<template>
  <main>
    <article v-for="article in articles.items" v-show="$isAllowed('read')">
      <h1>{{ article.title }}</h1>

      <router-link :to="`/article/${article.id}/edit`" v-show="$article.isAllowed('update', article)">
        Edit Article
      </router-link>

      <p>{{ article.content }}</p>

      <p>{{ $article.secretNotes() }}</p>
    </article>
  </main>
</template>

<script>
  import { mapState } from 'vuex';

  export default {
    computed: {
      ...mapState([
        'articles'
      ])
    },

    // add your perimeters
    perimeters: [
      articlesPerimeter
    ]
  }
</script>

In example above we have injected our articlesPerimeter into our component. Our component act as sandbox now. We can call all the methods that are available in the Sandbox directly on our component.

Protecting Routes

import Router from 'vue-router';
import { createSandbox } from 'vue-kindergarten';

import Home from '@/components/Home';
import Articles from '@/components/Articles';
import EditArticle from '@/components/EditArticle';
import RouteGoverness from '@/governesses/RouteGoverness';

import articlesPerimeter from '@/perimeters/articlesPerimeter';

import child from '@/child';

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },

    {
      path: '/articles',
      name: 'articles',
      component: Articles,
      meta: {
        perimeter: articlesPerimeter,
        perimeterAction: 'read',
      }
    },

    {
      path: '/articles/:id/edit',
      name: 'edit-article',
      component: EditArticle,
      meta: {
        perimeter: articlesPerimeter,
        perimeterAction: 'update',
      }
    }
  ]
});

router.beforeEach((to, from, next) => {
  to.matched.some((routeRecord) => {
    const perimeter = routeRecord.meta.perimeter;
    const Governess = routeRecord.meta.governess || RouteGoverness;
    const action = routeRecord.meta.perimeterAction || 'route';

    if (perimeter) {
      const sandbox = createSandbox(child(), {
        governess: new Governess(),

        perimeters: [
          perimeter,
        ],
      });

      return sandbox.guard(action, { to, from, next });
    }

    return next();
  });
});

export default router;

Route Governess

import { HeadGoverness } from 'vue-kindergarten';

export default class RouteGoverness extends HeadGoverness {
  guard(action, { next }) {
    // or your very own logic to redirect user
    // see. https://github.com/JiriChara/vue-kindergarten/issues/5 for inspiration
    return this.isAllowed(action) ? next() : next('/');
  }
}

Usage with Nuxt.js

Register plugin in plugins/vue-kindergarten.js:

import Vue from 'vue';
import VueKindergarten from 'vue-kindergarten';

import child from '~/child';

Vue.use(VueKindergarten, {
  child
});

Implement your child getter in child.js:

export default (store) => store && store.state.user;

Add reference to your plugin inside of nuxt.config.js:

module.exports = {
  plugins: ['~/plugins/vue-kindergarten']
};

You can now use vue-kindergarten in your Nuxt templates.

To protect our routes we need to create a Nuxt middleware in middleware/vue-kindergarten:

import { createSandbox } from 'vue-kindergarten';
import RouteGoverness from '~/governesses/RouteGoverness';

import child from '~/child';

export default (context) => {
  const { route, error, redirect, store, isServer } = context;
  route.matched.some((routeRecord) => {
    const options = routeRecord.components.default.options;
    const perimeter = options.routePerimeter;
    const Governess =  options.routeGoverness || RouteGoverness;
    const action = options.routePerimeterAction || 'route';

    if (perimeter) {
      const sandbox = createSandbox(child(store), {
        governess: new Governess(context),

        perimeters: [
          perimeter,
        ],
      });

      return sandbox.guard(action, { redirect });
    }
  });
}

and again register your middleware in you Nuxt config:

module.exports = {
  plugins: [
    '~/plugins/vue-kindergarten'
  ],

  router: {
    middleware: 'vue-kindergarten'
  },
};

This middleware will look in you component for routePerimeter and for routePerimeterAction and will check if the condition passes with the currently logged-in user.

import { createPerimeter } from 'vue-kindergarten';

import articlesPerimeter from '~/perimeters/articles';

// This component will only be accessible if user can update articles
export default {
  routePerimeter: articlesPerimeter,
  routePerimeterAction: 'update'
}

The implementation of your default routing governess might look like this:

import { HeadGoverness } from 'vue-kindergarten';

export default class RouteGoverness extends HeadGoverness {
  guard(action, { redirect }) {
    if (this.isNotAllowed(action)) {
      redirect('/');
    }
  }
}

You can also implement you own governess per each component to define a different redirect logic based on context:

import { createPerimeter } from 'vue-kindergarten';

import articlesPerimeter from '~/perimeters/articles';
import ArticlesRoutingGoverness from '~/governesses/ArticlesRoutingGoverness';

// This component will only be accessible if user can update articles
export default {
  routePerimeter: articlesPerimeter,
  routePerimeterAction: 'update',
  routeGoverness: ArticlesRoutingGoverness
}

More About Vue-Kindergarten

Role Based Authorization for your Vue.js and Nuxt.js Applications Using vue-kindergarten

License

The MIT License (MIT) - See file 'LICENSE' in this project

Copyright

Copyright © 2017 Jiří Chára. All Rights Reserved.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].