Coder Social home page Coder Social logo

anthonygore / vue-router-user-roles Goto Github PK

View Code? Open in Web Editor NEW
240.0 11.0 27.0 308 KB

A Vue.js plugin that protects routes based on user roles. Add your own authentication.

License: MIT License

JavaScript 100.00%
vue vue-router permissions protected roles authorization

vue-router-user-roles's Introduction

vue-router-user-roles

Build status Coverage Status

npm vue2

A plugin for Vue.js SPAs that protects routes depending on user role. Add your own authentication.

๐Ÿ“– Usage

Check out the demo here.

Installation

$ npm i vue-router-user-roles

First create a Vue Router instance. It's best to do this in a dedicated file and export as a module e.g.

// router.js

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

export default new VueRouter(...);

Now you can add this plugin in your main file. You must pass in a router instance as an option router.

// main.js

import Vue from "vue";
import router from "./router";
import VueRouterUserRoles from "vue-router-user-roles";

Vue.use(VueRouterUserRoles, { router });

Protecting routes

To protect a route, add a permissions property to each route configuration object under the meta property.

Assign an array of objects to this, with each object defining the permissions for a different user role.

The three properties required for permissions objects are:

  • role - the user role being configured for this route.
  • access - either a boolean, or function returning a boolean, that defines access for the user. A function will have access to two objects: the user object and the route being accessed.
  • redirect - a route name you wish to redirect to if the user does not have access.
let opts = {
  routes: [
    {
      path: "/protected",
      name: "protected",
      component: Protected,
      meta: {
        permissions: [
          {
            role: "guest",
            access: false,
            redirect: "login"
          }
        ]
      }
    },
    {
      path: "/profile/:id",
      name: "profile",
      component: Profile,
      meta: {
        permissions: [
          {
            role: "registered",
            access: (user, to) => user.id === to.params.id,
            redirect: "login"
          },
          {
            role: "guest",
            access: false,
            redirect: "login"
          }
        ]
      }
    }
  ]
};

const router = new VueRouter(opts);

User

A "user" is an object with one required property: role. Typically this would be set to a string e.g. "guest", "admin" etc.

You can add other properties to this object. You may want to do that if route access is determined by a function, since the function is passed this object. For example, you may create an id property that could be compared to a route parameter e.g /user/:id

Once the plugin is installed, you can access user from within your Vue instance or any component as this.$user.

Set the user

You can set a user with the set method. Here's an example of setting the user before the first instance of Vue is created:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import VueRouterUserRoles from "vue-router-user-roles";

Vue.use(VueRouterUserRoles, router);

// This would usually be an AJAX call to the server or a cookie check
// Let's assume the user hasn't logged in yet so they're a guest for now.
let authenticate = Promise.resolve({ role: "guest" });

authenticate.then(user => {
  Vue.prototype.$user.set(user);
  new Vue({
    render: h => h(App),
    router
  }).$mount("#app");
});

You'll probably set the user again during the lifecycle of the app. For example, a user may start as a guest, but once they're authenticated their role and permissions will change.

You can access user from within the app as this.$user e.g.

export default {
  methods: {
    logIn(username, password) {
      authenticate("/api/user", { username, password })
        .then(user => {
          this.$user.set(Object.assign(user, { role: "registered" }));
        });
    },
    logOut() {
      this.$user.set({ role: "guest" });
    }
  }
}

The user object is reactive, so each time you set the user, permissions will be reassessed and will potentially redirect the page if the user no longer has access to the current route.

The other API method available is get:

<template>
  <div v-if="$user.get().role === 'guest'">...</div>
</template>

๐Ÿ“œ Changelog

Details changes for each release are documented in the CHANGELOG.md.

โ— Issues

Please make sure to read the Issue Reporting Checklist before opening an issue. Issues not conforming to the guidelines may be closed immediately.

๐Ÿ’ช Contribution

Please make sure to read the Contributing Guide before making a pull request.

ยฉ๏ธ License

MIT

vue-router-user-roles's People

Contributors

anthonygore avatar dfcook avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-router-user-roles's Issues

Question: best way to keep user state on refresh page?

I've just implemented this library on my first apollo/vue project ๐Ÿ”ฅ

I love the way you thinked your lib <3 but still have a question! And I think I'll not be the unique one with this question.

After login an user and provide his payload on the $user what's your recommendation to keep the user logged in ($user hydrated) also with browser refresh ?

I've thinked to keep my user's JWT's token on the localStorage and at each refresh just query my API to verify the JWT and re-populate my data on $user.

Another practice or maybe a good practice ?? ๐Ÿ˜„

PS : I can probably contributing to your documentation to add this point. It can be helpfull for other developers who want to implement your lib.

Cheers <3

Things that need to be done

  • Setup linter correctly.
  • Setup testing. Currently karma is being used. Remove that and replace with Jest.
  • Create unit tests.
  • Setup circleci.
  • e2e tests

Feature ideas:

  • $user.hasAccess({ name: "routename" }). This could be useful for conditionally displaying links depending on access.
  • $user.set({...}, { redirect: false }). Stop the page from automatically redirect when setting a user.

Other:

  • Usage with Vuex?

Handle dynamic parameter routes

Thanks for this library - it is very useful. One feature request please:

Handle dynamic routes. My app requires no logins, because it's using Windows Auth and AD. I have a Vue component that handles errors, which takes a route parameter for the error code, e.g. for unauthorized user I would pass 403 as the code for Forbidden, and the page would display something specific relating to that issue (want to request access? blah blah):

      {
        role: "guest",
        access: false,
        redirect: "oops/403"
      }

But it seems this does not work.

Your consideration would be much appreciated.

Protected content appears before role validation is complete

vue & vue-router-permissions version

Vue -- 2.5.21
Vue Router -- 3.0.2

Reproduction Link

Out of the box

Steps to reproduce

Setup access per documentation. Notice how when you have a protected route, it will flash before redirecting when access is not allowed.

What is Expected?

Protected content will not be shown during access validation. Should most likely tie into VueRouter's navigation guards logic (ie beforeEach) to bring validation higher up the chain.

What is actually happening?

Protected content is appearing on screen before access validation is performed and executed.

so many errors

lost role property after reload page, and how use role, if I want not one ROLE?

Missing module file on package.json

package.json has wrong module file "module": "dist/vue-router-user-roles.esm.js",, that file doesn't exists

vue & vue-router-permissions version

vue 2.6.14
vite 2.7.12
vue-router-user-roles 0.1.92

Reproduction Link

Steps to reproduce

run yarn dev

What is Expected?

No errors

What is actually happening?

Vite get error message
[plugin:vite:import-analysis] Failed to resolve entry for package "vue-router-user-roles". The package may have incorrect main/module/exports specified in its package.json: Failed to resolve entry for package "vue-router-user-roles". The package may have incorrect main/module/exports specified in its package.json.

Installation instruction why with -D in the end?

First off, sorry for opening this issue for this, but I didn't see a way to mention this other wise.

Why is there a -D appended in the installation instructions? I understand -D flags for installations in dev-dependencies, but I would like this functionality to be available in production as well. Am I missing something?

Read me part is missing !!!

vue & vue-router-permissions version

vue: 2.6.4
vue-router: ^3.0.2

Reproduction Link

Out of the box

Steps to reproduce

Setup access per documentation. Notice how when you have a protected route, it will flash before redirecting when access is not allowed.

What is Expected?

read me part is missing.

What is actually happening?

Correct the read me part. Because npm package name is missing.

e9faca86-fd20-4fa8-b86a-b92a2debb2cb

Does this login flow look doable?

Just seen this, looks like a great project!

I have this login flow using Amazon Cognito for the user login, but I also want to load site data when the site first loads, and user data after login or site reload (when there will be an auth token in local storage, but no user data).

image

I'm pretty sure it's my final flow.

You think it's doable with your plugin?

User with multiple roles

Hi, thanks for the great lib - real timesaver!

Is it possible to handle a user with multiple roles though as we have this requirement now?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.