系统开发中按钮级权限控制也是非常重要的功能之一,可以严格控制不同角色用户所拥有的功能权限。
首先可以通过vue的自定义指令来控制按钮(div,link也阔以)等的显示与否以及是否禁用状态。具体可查看官方文档vue自定义指令。
/**
* 定义vue permission指令
*
* el:指令所绑定的元素,可以用来直接操作 dom
* binding:一个对象,包含以下属性:
* name:指令名,不包括 v- 前缀。
* value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
* oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子
* 中可用。无论值是否改变都可用。
* expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
*/
Vue.directive('permission', function (el, binding) {
// 检查是否有该code代表的权限or该code是否为禁用状态,并将对应的dom进行相应的控制(没有则隐藏,禁用则置灰不可点击)
// 前端可在登录后将拥有的菜单以及权限的树结构存于sessionStorage,也可每次进入页面后单独请求api判断是否存在等。
Permission.checkCodeAndSetDom(binding.value, el);
})
在功能模块定义各自的permission.js文件用于设置需要控制的权限的code,uri,请求方法等。const code = {
// 菜单列表页面相关
menu: {
// 保存资源权限
save: Permission.code("resource:save").uri("/sys/resources").method(method.POST),
}
}
export default code;
在vue页面中对需要控制的按钮等使用v-permission指令,并可对权限相关联的uri进行请求,并返回结果// 对要限制的按钮进行控制
<el-button v-permission="permission.save.code"
type="primary" icon="el-icon-plus" @click="addResource(false)">添加</el-button>
// 以下是script区
// 导入permission.js文件
import permissions from '../permissions.js'
export default {
data() {
// 设置save权限
savePermission: permissions.menu.save
},
methods: {
// 在method中定义的按钮click事件方法
async addResource() {
// 该方法会用在permission.js文件中指定该权限的请求uri和请发方法发送请求,并获取响应结果
let res = await this.savePermission.requset(this.form);
....
}
}
}
以下为上述功能所需要依赖的Permission类
import request from './request'
import Config from './config'
/**
* show: 菜单按钮是否显示
* disabled: 菜单功能是否被禁用
*/
class PermissionInfo {
constructor(show, disabled) {
this.show = show;
this.disabled = disabled;
}
}
/**
* 可用于各模块定义各自权限对象
*/
class Permission {
constructor(code) {
this.code = code;
}
/**
* 权限对应的uri
* @param {String} uri 请求uri
*/
uri(uri) {
this.uri = uri;
return this;
}
/**
* uri的请求方法(方法枚举)
* @param {Number} method 请求方法
*/
method(method) {
this.method = method;
return this;
}
/**
* 获取权限的完整url
*/
getUrl() {
return request.getApiUrl(this.uri);
}
/**
* 操作该权限,即请求对应的uri
* @param {Object} param 请求该权限的参数
*/
request(param) {
return request.send(this, param);
}
/** 静态方法 **/
/**
* 静态工厂,设置code,并返回Permission对象
* @param {String} code 权限code(权限标识符)Permission对象必有的属性
*/
static code(code) {
return new Permission(code);
}
/**
* 登录成功保存对应的token以及菜单按钮列表
*/
static savePermission(tokenMenuAndPermission) {
//保存token
Permission.saveToken(tokenMenuAndPermission.token);
//保存menus
sessionStorage.setItem(Config.name.resourcesKey, JSON.stringify(tokenMenuAndPermission.resources));
}
/**
* 获取token
*/
static getToken() {
return sessionStorage.getItem(Config.name.tokenKey);
}
/**
* 保存token
* @param {Object} token token
*/
static saveToken(token) {
sessionStorage.setItem(Config.name.tokenKey, token);
}
/**
* 从sessionStorage所有permissions获取指定permission对象的PermissionInfo
*/
static getPermission(code) {
// 超级管理员通行
// if (JSON.parse(sessionStorage.getItem(Config.name.adminKey)).username == 'admin') {
// return new PermissionInfo(true, false);
// }
let menus = JSON.parse(sessionStorage.getItem(Config.name.resourcesKey));
for (let menu of menus) {
let leafs = Permission.getLeafs(menu);
// 获取菜单的所有叶子节点
for (let p of leafs) {
// 如果是菜单类型,则跳过
if (p.type === 1) {
continue;
}
if (p.code === code) {
// 如果是禁用状态,则禁止按钮点击
if (p.status === 0) {
return new PermissionInfo(true, true);
}
return new PermissionInfo(true, false);
}
}
}
return new PermissionInfo(false, true);
}
/**
* 获取菜单的所有叶子节点
* @param {Object} menu 根菜单
*/
static getLeafs(menu) {
let leafs = [];
Permission.fillLeafs(menu, leafs);
return leafs;
}
/**
* 将所有叶子节点填充
* @param {Object} meun 根菜单
* @param {Object} leafs 需要填充的叶子节点
*/
static fillLeafs(menu, leafs) {
let children = menu.children;
if (!children) {
leafs.push(menu);
return;
}
children.forEach(m => {
Permission.fillLeafs(m, leafs);
})
}
/**
* 检查权限code并设定对应dom的属性
* @param code 权限码
* @param elDom dom元素
*/
static checkCodeAndSetDom(code, elDom) {
// 根据权限code获取对应权限信息
let permission = Permission.getPermission(code);
// 如果没有显示权限,则隐藏该元素
if (!permission.show) {
elDom.style.display = 'none';
}
// 如果该权限被暂用,则禁止该btn
if (permission.disabled) {
// 将按钮置为禁用
elDom.setAttribute('disabled', 'disabled');
// element-ui需要添加该类样式
elDom.className = elDom.className + ' ' + 'is-disabled';
}
}
}
export default Permission
到此为止前端的按钮,link, div等的权限控制就差不多了。再提一点的就是权限code就是与指定资源操作相关联的一个标识符。
当然前端权限是控制了,但是后端也需要对其进行相对应的控制才可以真正实现控制,具体的后端权限控制方案or完整的前端控制案例,可查看 https://gitee.com/objs/mayfly 项目中有完整的使用案例。
在 Native 开发中,Android 和 IOS 平台都在系统层面直接提供给了应用开发识别图像的一些能力,比如对于二维码/条形码的识别,Android 可以使用 barcode API 、 iOS 可以使用 CIQRCodeFeature API 。
Js的API设计原则总共包含了七个大块。系卤煮自己总结的一些经验和教训。本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来。很难做到详尽充实,如果有好的建议或者不对的地方,还望不吝赐教斧正。
现在越来越流行前后端分离开发,使用ajax交互。所以api接口文档就变的十分有意义了,目前市场有哪些比较优秀的接口文档管理工具呢?比如:MinDoc,eoLinker,apizza,RAML,Swagger等等
无论网站,还是App目前基本都是基于api接口模式的开发,那么api的安全就尤为重要了。目前攻击最常见的就是“短信轰炸机”,由于短信接口验证是App,网站检验用户手机号最真实的途径,使用短信验证码在提供便利的同时,也成了呗恶意攻击的对象,那么如何才能防止被恶意调用呢?
整理提供最新的各种免费JSON接口,其中有部分需要用JSONP调用。方面前端同学的学习或在网站中的使用,包括:免费的天气预报、地图、IP、手机信息查询、翻译、新闻等api接口
要弄清楚什么是RESTful API,首先要弄清楚什么是REST。REST -- REpresentational State Transfer,英语的直译就是“表现层状态转移”。如果看这个概念,估计没几个人能明白是什么意思。
Fetch API 已经作为现代浏览器中异步网络请求的标准方法,其使用 Promise 作为基本构造要素。Fetch 在主流浏览器中都有很好的支持,除了IE。
随着移动互联网的发展, 基于互联网的应用正变得越来越普及,在这个过程中,更多的平台将自身的资源开放给开发者来调用。对外提供的API 调用使得平台之间的内容关联性更强,同时这些开放的平台也为用户、开发者和中小网站带来了更大的价值。
环境centos,添加deamon.json后,dockerd命令可以启动docker,这时请求 127.0.0.1:2375 可以正常访问,使用systemctl无法启动docker的情况.无法启动docker:查看当前的docker配置
你是否正在设计第一个Web应用程序?也许你过去已经建立了一些,但是目前也正在寻找语言的变化以提高你的技能,或尝试新的东西。有了所有信息,就很难决定为下一个产品或项目选择哪种编程语言。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!