All Projects → OneWayTech → Vue Auth Solution

OneWayTech / Vue Auth Solution

Vue 权限管理解决方案

Projects that are alternatives of or similar to Vue Auth Solution

Gobblin
A distributed data integration framework that simplifies common aspects of big data integration such as data ingestion, replication, organization and lifecycle management for both streaming and batch data ecosystems.
Stars: ✭ 2,006 (+893.07%)
Mutual labels:  management
Redis Adapter
Redis adapter for Casbin
Stars: ✭ 167 (-17.33%)
Mutual labels:  auth
Go Os
Stars: ✭ 185 (-8.42%)
Mutual labels:  auth
Seagull
Friendly Web UI to manage and monitor docker
Stars: ✭ 1,904 (+842.57%)
Mutual labels:  management
Sanctum
Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.
Stars: ✭ 2,172 (+975.25%)
Mutual labels:  auth
Wp Graphql Jwt Authentication
Authentication for WPGraphQL using JWT (JSON Web Tokens)
Stars: ✭ 172 (-14.85%)
Mutual labels:  auth
Ifarm
后台管理系统,前后端分离,后端SpringBoot+Shiro+MyBatis+Redis,前端Vue+ElementUI+Axios
Stars: ✭ 151 (-25.25%)
Mutual labels:  management
Laravel Adminless Ldap Auth
Authenticate users in Laravel against an adminless LDAP server
Stars: ✭ 199 (-1.49%)
Mutual labels:  auth
Atutor
NO LONGER USER LEVEL SUPPORTED. CONTRIBUTING DEVELOPERS INTERESTED IN MAINTAINING ATUTOR, SHOULD REQUEST COLLABORATOR ACCESS. : ATutor is an Open Source Web-based Learning Management System (LMS) used to develop and deliver online courses. Administrators can install or update ATutor in minutes, develop custom themes to give ATutor a new look, and easily extend its functionality with feature modules. Educators can quickly assemble, package, and redistribute standardized Web-based instructional content, easily import prepackaged content, and conduct their courses online. Students learn in an accessible, adaptive, social learning environment.
Stars: ✭ 166 (-17.82%)
Mutual labels:  management
Huge
Simple user-authentication solution, embedded into a small framework.
Stars: ✭ 2,125 (+951.98%)
Mutual labels:  auth
Food Ordering System
Food or Item Order Management System
Stars: ✭ 161 (-20.3%)
Mutual labels:  management
Happypanda
A cross platform manga/doujinshi manager with namespace & tag support
Stars: ✭ 161 (-20.3%)
Mutual labels:  management
Laravel Auth Checker
Laravel Auth Checker allows you to log users authentication, devices authenticated from and lock intrusions.
Stars: ✭ 177 (-12.38%)
Mutual labels:  auth
Engineering Management
A collection of inspiring resources related to engineering management and tech leadership
Stars: ✭ 2,520 (+1147.52%)
Mutual labels:  management
Cfpmp
Cloudflare Partner Management Panel
Stars: ✭ 194 (-3.96%)
Mutual labels:  management
Gophertunnel
Toolbox for Minecraft software written in Go
Stars: ✭ 156 (-22.77%)
Mutual labels:  auth
Swarmpit
Lightweight mobile-friendly Docker Swarm management UI
Stars: ✭ 2,255 (+1016.34%)
Mutual labels:  management
Knative Lambda Runtime
Running AWS Lambda Functions on Knative/Kubernetes Clusters
Stars: ✭ 201 (-0.5%)
Mutual labels:  management
Wifidog Ng
Next generation WifiDog implemented in Lua.
Stars: ✭ 197 (-2.48%)
Mutual labels:  auth
Poshkeepass
PowerShell module for KeePass
Stars: ✭ 177 (-12.38%)
Mutual labels:  management

§ Vue 权限控制

在看本文档之前,您需要阅读 Vue 另类状态管理

业界一向认为,权限只能是后端做
但如果在前后端分离的前提下仍是这样实现,那么前后端分离是没有任何意义的,还不如直接后端渲染实在

目前有关 Vue 的权限控制并没有一个相对主流的解决方案,故在此抛砖引玉

首先先说明,我司并没有用 Vuex,仅仅就是 Vue + Vue Router
稍微复杂一点的业务场景,都可以使用上述的“另类状态管理”以及 eventbus 去解决


⊙ 概览

一般我们项目的源码目录 src/ 下都会有一个 mixins/,里面必然存在一个 session.js,有如:

我司约定 mixin 中的变量以及函数都应当使用 $ 结尾(为什么不能用在开头?因为 Vue 不会代理 $ / _ 开头的变量,故统一置尾)

/*** src/mixins/session.js ***/
import authService from '@/services/authService' // 权限相关的 API 封装服务
const goToSSO = () => {
  location.replace(`<我司单点登录 URL>?returnUrl=${encodeURIComponent(location.href)}`)
}

/* 登录凭据 */
export const session$ = {
  id: null,
  username: '',
  role: '',
  isLeader: null
}

/* 是否管理员 */
export const isAdmin$ = () => {
  return session$.role === 'admin'
}

/* 是否销售主管 */
export const isSalesLeader$ = () => {
  return session$.role === 'sales' && session$.isLeader
}

/* 挂载 DOM 前调用本函数 */
export const syncSession$ = () => {
  return authService.getSession().then(sess => {
    Object.assign(session$, sess) // 这里不建议写成 session$ = sess
  }).catch(() => {
    goToSSO() // 跳转到单点登录
    throw new Error('Redirecting to SSO') // 继续抛出,避免之后的 then 执行挂载 DOM
  })
}

// @export.default <mixin>
export default {
  data: () => ({
    session$
  }),
  computed: {
    isAdmin$,
    isSalesLeader$
  },
  methods: {
    logout$ () {
      authService.logout().then(goToSSO)
    }
  }
}

在启动文件中一般是这样的:

/*** src/app.js ***/
import 'babel-polyfill'
import Vue from 'vue'
import App from '@/components/App'
import { syncSession$ } from '@/mixins/session'

// 同步 session 后才挂载 DOM
syncSession$().then(() => {
  /* eslint-disable no-new */
  new Vue({
    el: '#app',
    router: require('@/routes/').default, // 路由涉及权限,因此须在同步 session 后才执行
    render: h => h(App)
  })
})

以上就是我司权限管理的基石


⊙ 常见的疑问

Q:为什么不使用 LocalStorage / SessionStorage / cookies 去保存登录凭据?这样可以全局访问很方便啊
A:可被篡改,没有安全性可言,而且还得考虑其过期时间以及解析错误等一系列不必要的麻烦

Q:用 mixin 全局共享状态的好处是什么?
A:首先必须指出,要想让 session$ 变成响应式,您必须要把 src/mixins/session.js 引入到任一组件中,这样就可以在组件内部(包括模板)访问到所有的变量与方法。而且,您还可以在非组件内部中访问。虽然 export default 的是 mixin 的固定格式,但 export 的却是直接的变量或方法,因此可以直接 import { session$ } from '@/mixins/session',这几乎就像全局变量般便利,但又可以最大程度地保证安全性。更重要的,您还可以享受 Vue 带来的全局响应式、计算属性等一系列特性,而不仅仅是一个无法被外界篡改的闭包变量。举例说明:

import session from '@/mixins/session'

export default {
  mixins: [session],
  watch: {
    /* 需求:测试模式下允许即时修改用户角色,请在控制台显示 */
    'session$.role' (newRole, oldRole) {
      console.info('角色已切换:', oldRole, ' => ', newRole)
    }
  }
}

Q:路由控制怎么处理?
A:下面我们接着说


⊙ 路由级别控制

能在 Vue 层面上解决的事情没必要动用到 Vue Router 的特性,否则权限就写得太散了
业内主流的方式都是通过 beforeEach 来获取 meta 信息以拦截
不过话说回来,既然你都不想该角色看到的路由,为什么你还要挂载?画蛇添足多此一举莫过于此

举个例子,一个项目有 /a(默认)、/b/c/d/e 五个路由,需满足:

  • 只有 管理员 可以看到 /e
  • 只有 管理员 与 销售 Leader 可以看到 /d

那么路由的定义可以这样写:

import { isAdmin$, isSalesLeader$ } from '@/mixins/session'

export default [
  {
    path: '/a',
    alias: '/',
    component: require('@/views/a/')
  },

  {
    path: '/b',
    component: require('@/views/b/')
  },

  {
    path: '/c',
    component: require('@/views/c/')
  },

  (isAdmin$() || isSalesLeader$()) && {
    path: '/d',
    component: require('@/views/d/')
  },

  isAdmin$() && {
    path: '/e',
    component: require('@/views/e/')
  },
  
  { // 404 置尾
    path: '*',
    component: {
      beforeCreate () {
        this.$router.replace('/')
      },
      render: h => null
    }
  }
].filter(route => route) // 排除掉为 false 的项

这下你能可以理解为什么在启动文件中要在 syncSession$ 完成后才引入路由了吧?
如果在开头就 import routes from '@/routes/' 则无法实现控权(因为是先执行)


⊙ 按钮级别控制

基本就是把 @/mixins/session 引入到组件中就可以了,没有任何难度



2017/12/6 针对 SegmentFault 下评论的更新

  • 针对 没有用动态路由,导致用户登录前不能初始化Vue应用,所以登陆页只能单独做,开始我也是这么做的,但始终觉得url跳转的体验不好,所以用动态路由解决了 的解决方案:如果您的公司没有 SSO,那么每个项目都只能重复造轮子做登录页(之前我司就是如此),此时只能借助 vue-router 的钩子函数 beforeEach 控权:
import { isLogin$ } from '@/mixins/session'
const LOGIN_PATH = '/auth/login'

export default function authInterceptor(to, from, next) {
  if (isLogin$()) {
    switch (to.path) {
      case LOGIN_PATH:
        next('/')
        return
      default:
        next()
    }
  } else {
    switch (to.path) {
      case LOGIN_PATH:
        next()
        return
      default:
        next(`${LOGIN_PATH}?referrer=${encodeURIComponent(to.fullPath)}`)
    }
  }
}

// 使用方式:router.beforeEach(authInterceptor)
  • 针对 在前端路由文件中根据角色做判断的做法不够灵活,路由权限还是由后端分发给前端比较好,这样当需要修改角色权限时,后端改一下配置,前端刷新就生效了 的回应:把我司现行完善的权限设计一股脑搬出来说没有意义,以上例子只是为了简要说明,更重要的是思想
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].