- A+
所属分类:.NET技术
RBAC实现最基础的权限管理webapi+vue
一、确定关系表
//权限管理表 这个表可以实现左侧菜单的显示
[Table("Permission")]
public class Permission
{
[Key]
public int Id { get; set; }
public string PermissionCode { get; set; }
public string PermissionName { get; set; }
public string PermissionIco { get; set; }
public string PermissionUrl { get; set; }
public bool Enable { get; set; } = true;
public string ParentCode { get; set; }
}
//角色表
[Table("Role")]
public class Role
{
[Key]
public int Id { get; set; }
[Required,StringLength(50)]
public string RoleName { get; set; }
public string Desc { get; set; }
public string PermissionName { get; set; }
public string Users { get; set; }
}
//用户表
/// <summary>
/// 用户表
/// </summary>
[Table("User")]
public class User
{
[Key]
public int Id { get; set; }
public int DeptId { get; set; }
[Required,StringLength(20)]
public string UserName { get; set; }
[Required, StringLength(40)]
public string Password { get; set; }
public SexType SexType { get; set; }
[StringLength(100)]
public string Email { get; set; }
public string RoleIds { get; set; }
public string DepaCodes { get; set; }
}
public enum SexType
{
男,
女,
保密
}
//这张表用来关联角色和权限
/// <summary>
/// 角色权限
/// </summary>
[Table("Role_Permission")]
public class Role_Permission
{
[Key]
public int Id { get; set; }
public int RoleId { get; set; }
public int PermissionId { get; set; }
}
//用户和角色表 用来关联用户和角色
[Table("User_Role")]
public class User_Role
{
[Key]
public int Id { get; set; }
public int UserId { get; set; }
public int RoleId { get; set; }
}
二、写接口
根据用户id显示权限的接口
//这个是权限管理的接口和实现 使用的是依赖注入的方式
public interface IPermissionRespository
{
//这里的dto是实现左侧菜单的递归实现
List<MenoDto> GetPermissions(int userId);
}
public class PermissionRespository : IPermissionRespository
{
private readonly AppDbContext appDbContext;
public PermissionRespository(AppDbContext appDbContext)
{
this.appDbContext = appDbContext;
}
//根据用户id查询权限显示左侧列表
public List<MenoDto> GetPermissions(int userId)
{
//先查询最高级的数据 然后一次查询子集
//if(userId == 1) return GetMenus(this.appDbContext.permissions.ToList(), "M");
//使用ling语句实现三表联查 最后显示权限信息
var menus = (from a in this.appDbContext.user_roles
join b in this.appDbContext.role_Permissions
on a.RoleId equals b.RoleId
join c in this.appDbContext.permissions
on b.PermissionId equals c.Id
where a.UserId == userId
select new Permission
{
Id = c.Id,
Enable = c.Enable,
ParentCode = c.ParentCode,
PermissionName = c.PermissionName,
PermissionCode = c.PermissionCode,
PermissionIco = c.PermissionIco
}).ToList();
var list = GetMenus(menus, "M");
return list;
}
//使用递归查询左侧菜单
public List<MenoDto> GetMenus(List<Permission> list,string permissionCode)
{
List<MenoDto> menus = new List<MenoDto>();
foreach (var item in list.Where(u=>u.PermissionCode == permissionCode))
{
var menu = new MenoDto();
menu.Id = item.Id;
menu.PermissionName = item.PermissionName;
menu.PermissionCode =item.PermissionCode;
menu.PermissionUrl = item.PermissionUrl;
menu.PermissionIco = item.PermissionIco;
menu.Enable = item.Enable;
menu.ParentCode = item.ParentCode;
menu.menoDtos = GetMenus(list, item.ParentCode);
menus.Add(menu);
}
return menus;
}
}
角色接口及实现
//角色接口
public interface IRoleRespository
{
ApiResultData GetRole(); //显示角色全部信息 返回的是自己封装的api规范
int AddRole(Role role);
/// <summary>
/// 添加角色和权限关系表
/// </summary>
/// <param name="roleId"></param>
/// <param name=""></param>
/// <returns></returns>
int AddRole_Permission(int? roleId,string permissionIds);
ApiResultData GetRole_Permission(int roleId);
Role GetRole(int id);
}
//接口实现
public class RoleRespository : IRoleRespository
{
private readonly AppDbContext appDbContext;
public RoleRespository(AppDbContext appDbContext)
{
this.appDbContext = appDbContext;
}
//添加角色信息
public int AddRole(Role role)
{
this.appDbContext.roles.Add(role);
return this.appDbContext.SaveChanges();
}
//添加角色的权限 实现一对多 一个角色可以有多个权限
public int AddRole_Permission(int? roleId, string permissionIds)
{
try
{
//判断角色id是否为空
if (roleId == null||string.IsNullOrEmpty(permissionIds)) return 0;
//如果不为空删除角色全部权限
appDbContext.role_Permissions.RemoveRange(appDbContext.role_Permissions.Where(u=>u.RoleId == roleId));
//这里从新添加角色权限
foreach (var item in permissionIds.Split(','))
{
Role_Permission role_Permission = new Role_Permission();
role_Permission.RoleId = (int)roleId;
role_Permission.PermissionId = Convert.ToInt32(item);
appDbContext.role_Permissions.Add(role_Permission);
}
return this.appDbContext.SaveChanges();
}
catch (Exception)
{
throw;
}
}
//获取角色全部信息
public ApiResultData GetRole()
{
return new ApiResultData { Data = this.appDbContext.roles.ToList()};
}
//查询角色单个实体
public Role GetRole(int id)
{
var role = this.appDbContext.roles.Find(id);
return role;
}
//通过角色id 查找对应的权限id
public ApiResultData GetRole_Permission(int roleId)
{
return new ApiResultData
{
Data = appDbContext.role_Permissions.Where(u => u.RoleId == roleId
).Select(u => u.PermissionId)
};
}
}
用户信息的接口及实现
public interface IUserRespository
{
bool AddUser(User user); //添加用户信息
ApiResultData GetUserAll(); //获取所有用户信息
ApiResult Login(User user); //登陆
}
//实现接口
public class UserRespository : IUserRespository
{
private readonly AppDbContext appDbContext;
public UserRespository(AppDbContext appDbContext)
{
this.appDbContext = appDbContext;
}
//添加角色信息
public bool AddUser(User user)
{
//这里开启事务 因为需要操作两张表添加数据
using var begin = this.appDbContext.Database.BeginTransaction();
try
{
//这里添加用户信息 密码采用MD5加密方式 底下有代码
user.Password = Md5Helper.encrypt(user.Password);
this.appDbContext.users.Add(user);
this.appDbContext.SaveChanges();
//添加角色和用户关联的表
foreach (var item in user.RoleIds.Split(',')) //这里需要分割角色id 因为是多个id
{
User_Role user_Role = new User_Role();
user_Role.UserId = user.Id;
user_Role.RoleId = Convert.ToInt32(item); //这里需要把字符串id 转为数字类型
this.appDbContext.user_roles.Add(user_Role);
}
this.appDbContext.SaveChanges();
begin.Commit(); //关闭事务
return true;
}
catch (Exception)
{
begin.Rollback(); //回滚 如果有一张表操作失败 两个添加都不会执行
return false;
}
}
//获取用户的全部信息
public ApiResultData GetUserAll()
{
return new ApiResultData { Data = this.appDbContext.users.ToList()};
}
//实现登陆信息
public ApiResult Login(User user)
{
//通过 MD5对要登录的密码加密 然后从数据库查询账号密码
user.Password = Md5Helper.encrypt(user.Password);
User userInfor = this.appDbContext.users.FirstOrDefault(u=>u.UserName==user.UserName&&u.Password == user.Password);
if (userInfor == null) return new ApiResult { Code =ResponseCode.Fail , Data = userInfor, Message =GetEnumDescription.GetDescription(ResponseCode.Fail) }; //这里使用的返回类型是封装好的apiresult
return new ApiResult { Code = ResponseCode.Success, Data = userInfor,Message= GetEnumDescription.GetDescription(ResponseCode.Success) };
}
}
返回的apiresult MD5加密方式 还有DTO
//MD5加密方式
public static class Md5Helper
{
/// <summary>
/// MD5加密(32位)
/// </summary>
/// <param name="str">加密字符</param>
/// <returns></returns>
public static string encrypt(string str)
{
string cl = str;
string pwd = "";
MD5 md5 = MD5.Create();
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
for (int i = 0; i < s.Length; i++)
{
pwd = pwd + s[i].ToString("X");
}
return pwd;
}
}
//apiresult 接口返回的规范
public class ApiResult
{
public ResponseCode Code { get; set; } //状态码 类型是枚举
public string Message { get; set; } =string.Empty;
public dynamic Data { get; set; }
public bool Success =>Code== ResponseCode.Success; //这里是返回成功的状态
}
//左侧菜单返回的dto
public class MenoDto
{
public int Id { get; set; }
public string PermissionCode { get; set; }
public string PermissionName { get; set; }
public string PermissionIco { get; set; }
public string PermissionUrl { get; set; }
public bool Enable { get; set; } = true;
public string ParentCode { get; set; }
public List<MenoDto> menoDtos { get; set; }
}
//枚举类型 返回的状态码
// <summary>
/// 响应code枚举
/// </summary>
public enum ResponseCode
{
[Description("通用错误码")]
Fail = -1,
[Description("登录成功")]
Success = 200,
[Description("登录失败")]
LoginFail = 201,// 登录失败
/// <summary>
/// 未授权,需要重新登录
/// </summary>
[Description("未授权")]
Unauthorized = 401,
/// <summary>
/// 未授权,不需要重新登录,无权限操作
/// </summary>
[Description("未授权")]
Unauthorized1 = 1000, //未授权
[Description("未知异常")]
UnknownEx = 500, //未知异常标识
[Description("数据库异常")]
DbEx = 999, //数据库操作异常
[Description("数据为空")]
DataIsNull = 1002, //数据为空
[Description("数据格式错误")]
DataFormatError = 1003, //数据格式错误
[Description("数据错误")]
DataTypeError = 1004, //数据类型错误
[Description("数据验证失败")]
RequestDataVerifyFail = 1005, //请求数据验证失败
[Description("数据错误")]
UnityDataError = 1006, //统一数据处理错误码
}
//这个类是返回apiresult的时候 获取枚举的值
public static class GetEnumDescription
{
/// <summary>
/// 获取枚举的描述
/// </summary>
/// <param name="en"></param>
/// <returns></returns>
public static string GetDescription(Enum en)
{
//反射 获取枚举的类型
Type type = en.GetType();
//获取所有的成员
var members = type.GetMember(en.ToString());
if (members!=null && members.Length>0)
{
var desc = members[0].GetCustomAttributes(typeof(DescriptionAttribute),false);
if (desc!=null&&desc.Length>0)
{
return (desc[0] as DescriptionAttribute).Description;
}
}
return type.ToString();
}
}
控制器实现角色api 用户api 权限api
//权限api
[Route("api/[controller]/[action]")]
[ApiController]
[Authorize] //这里使用了JWT
public class PermissionController : ControllerBase
{
//依赖注入 使用权限的接口 还有redis的接口
private readonly IPermissionRespository permissionRespository;
private readonly IDistributedCache distributedCache;
public PermissionController(IPermissionRespository permissionRespository,
IDistributedCache distributedCache
)
{
this.permissionRespository = permissionRespository;
this.distributedCache = distributedCache;
}
//通过角色id获取权限
[HttpGet]
public IActionResult GetPermission(int userId)
{
//这里的key是角色的id
var key = $"userId_{userId}_menu";
//查询redis是否存入信息
var value = this.distributedCache.GetString(key);
if (string.IsNullOrEmpty(value))
{
//访问数据库
var list = this.permissionRespository.GetPermissions(userId);
this.distributedCache.SetString(key,
JsonConvert.SerializeObject(list), new
DistributedCacheEntryOptions().SetSlidingExpiration(System.TimeSpan.FromSeconds(6))
); //写入redis数据库 这里需要序列化为字符串
}
//从redis里面取的数据需要反序列化为list集合
var result = JsonConvert.DeserializeObject<dynamic>(this.distributedCache.GetString(key));
return Ok(result);
}
}
//用户api
[Route("api/[controller]/[action]")]
[ApiController]
public class UserController : ControllerBase
{
//依赖注入 角色接口 还有jwt鉴权 登陆成功返回token码 然后通过token码访问api接口
private readonly IUserRespository userRespository;
private readonly JwtToken jwtToken;
public UserController(IUserRespository userRespository, JwtToken jwtToken = null)
{
this.userRespository = userRespository;
this.jwtToken = jwtToken;
}
[HttpPost]
public IActionResult AddUser(User user)
{
return Ok(this.userRespository.AddUser(user));
}
[HttpGet]
public IActionResult GetUser()
{
return Ok(this.userRespository.GetUserAll());
}
[HttpPost]
[AllowAnonymous]
public IActionResult Login(User user)
{
var userInfor = this.userRespository.Login(user);
if (userInfor.Success) //判断是否登陆成功
{
User entity = userInfor.Data as User;
var token = jwtToken.GenerateToken(entity.UserName);
//JWT验证码存入响应头 前端登陆需要从头部获取token码
HttpContext.Response.Headers["token"] = token;
HttpContext.Response.Headers["Access-Control-Expose-Headers"] = "token";
return Ok(userInfor);
}
return BadRequest(userInfor); //状态码400
}
}
//角色api
[Route("api/[controller]/[action]")]
[ApiController]
public class RoleController : ControllerBase
{
private readonly IRoleRespository roleRespository;
public RoleController(IRoleRespository roleRespository)
{
this.roleRespository = roleRespository;
}
[HttpGet]
public IActionResult GetRole(int id)
{
var role = this.roleRespository.GetRole(id);
return Ok(role);
}
[HttpGet]
public IActionResult GetRoleList([FromServices] IMapper mapper)
{
var role = this.roleRespository.GetRole();
return Ok(role);
}
[HttpPost]
public IActionResult AddRole(Role role)
{
return Ok(this.roleRespository.AddRole(role));
}
[HttpPost]
public IActionResult AddRolePermission(int roleId,string permissionIds)
{
return Ok(roleRespository.AddRole_Permission(roleId,permissionIds));
}
[HttpGet]
public IActionResult GetRoleIdByPermissoins(int roleId)
{
var role = roleRespository.GetRole_Permission(roleId);
return Ok(role);
}
}
三、鉴权授权 ---JWT
授权的功能类 -----登陆功能用的这个 可以看用户api
public class JwtToken
{
public IConfiguration Configuration { get; }
public JwtToken(IConfiguration configuration)
{
this.Configuration = configuration;
}
/// <summary>
/// 生产令牌
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="expireMinutes">过期时间</param>
/// <returns></returns>
public string GenerateToken(string userName,int expireMinutes=30)
{
//获取发生人
var issuer = Configuration.GetSection("JwtSettings:Issuer").Value;
//获取的是密钥
var signKey = Configuration.GetSection("JwtSettings:SignKey").Value;
//上边两条数据从配置文件读取 在下面
var claims = new List<Claim>();
//添加主题
claims.Add(new Claim(JwtRegisteredClaimNames.Sub, issuer));
claims.Add(new Claim(JwtRegisteredClaimNames.Jti, userName));
//添加角色信息
claims.Add(new Claim("Role", "User"));
claims.Add(new Claim("userId", "Admin"));
var userClaimsIdentity = new ClaimsIdentity(claims);
//根据signKey 得到加密之后的key
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signKey));
//加密方式
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
// 建立 SecurityTokenDescriptor
var tokenDescriptor = new SecurityTokenDescriptor
{
Issuer = issuer,
//Audience = issuer, // 由於你的 API 受眾通常沒有區分特別對象,因此通常不太需要設定,也不太需要驗證
//NotBefore = DateTime.Now, // 預設值就是 DateTime.Now
//IssuedAt = DateTime.Now, // 預設值就是 DateTime.Now
Subject = userClaimsIdentity,
Expires = DateTime.Now.AddMinutes(expireMinutes),
SigningCredentials = signingCredentials
};
// 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
var serializeToken = tokenHandler.WriteToken(securityToken);
return serializeToken;
}
}
//配置文件
"RedisConnectionStrings": "127.0.0.1:6379,password=,defaultDatabase=0,connectTimeout=5000,syncTimeout=1000", //这里是连接redis的字符串
"JwtSettings": {
"Issuer": "JwtAuthDemo", //发行人
"SignKey": "ABCDEFOSAODIOJGOIEJF2902SJDFOISDJGOIJOIJ" //长度大于16个字符以上的字符串 //私钥
}
四、最重要的Startup类 完成接口的依赖注入 还有鉴权授权
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Week2", Version = "v1" });
#region 开启Swagger认证 这里实现的是api界面有一个验证token码的窗口 需要输入token码才能访问接口
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Description = "在下框中输入请求头中需要添加Jwt授权Token:Bearer Token",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
BearerFormat = "JWT",
Scheme = "Bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] { }
}
});
#endregion
});
//实现依赖注入
services.AddScoped<IPermissionRespository, PermissionRespository>();
services.AddScoped<IUserRespository, UserRespository>();
services.AddScoped<IRoleRespository, RoleRespository>();
services.AddSingleton<JwtToken>();
//配置Redis
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetSection("RedisConnectionStrings").Value;
//options.InstanceName = "SampleInstance";
});
//jwp鉴权
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
// 當驗證失敗時,回應標頭會包含 WWW-Authenticate 標頭,這裡會顯示失敗的詳細錯誤原因
options.IncludeErrorDetails = true; // 預設值為 true,有時會特別關閉
options.TokenValidationParameters = new TokenValidationParameters
{
// 透過這項宣告,就可以從 "sub" 取值並設定給 User.Identity.Name
NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
// 透過這項宣告,就可以從 "roles" 取值,並可讓 [Authorize] 判斷角色
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
// 一般我們都會驗證 Issuer
ValidateIssuer = true,
ValidIssuer = Configuration.GetValue<string>("JwtSettings:Issuer"),
// 通常不太需要驗證 Audience
ValidateAudience = false,
//ValidAudience = "JwtAuthDemo", // 不驗證就不需要填寫
// 一般我們都會驗證 Token 的有效期間
ValidateLifetime = true,
// 如果 Token 中包含 key 才需要驗證,一般都只有簽章而已
ValidateIssuerSigningKey = false,
// "1234567890123456" 應該從 IConfiguration 取得
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetValue<string>("JwtSettings:SignKey")))
};
});
}
//中间件需要添加
//鉴权
app.UseAuthentication();
//授权
app.UseAuthorization();
五、项目使用的nuget包如下
Microsoft.AspNetCore.Authentication.JwtBearer (5.0.16) //jwt鉴权
Microsoft.EntityFrameworkCore(5.0.16)
Microsoft.EntityFrameworkCore.Design (5.0.16)
Microsoft.EntityFrameworkCore.sqlServer (5.0.16)
Microsoft.EntityFrameworkCore.Tools (5.0.16)
Microsoft.Extensions.Caching.StackExchangeRedis (5.0.1) //redis缓存
Swashbuckle.AspNetCore (5.6.3)
六、前端vue
1.路由的配置
const routes = [
{
path: '/',
name: 'home',
redirect:'/login', //重定向登陆页面为初始化
component: Home,
children:[ //导航页面的子集
{
path: 'system/user', //跳转到用户页面
name: 'User',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/system/User.vue')
},
{
path: 'system/role', //跳转到角色页面
name: 'Role',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/system/Role.vue')
},
{
path: 'system/permission', //跳转到权限的页面
name: 'Permission',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/system/Permission.vue')
}
]
},
{
path: '/login',
name: 'Login',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue')
}
]
//路由守卫 判断token码是否为空 如果空跳转到登陆页面
router.beforeEach((to,form,next)=>{
//判断你要进入的是登陆页面,正常执行
if(to.path=='/login')next();
else{
let token = sessionStorage.getItem('token');
if(token==null||token == '') next('/login');
next();
}
})
封装axios的请求
//axios 又封装了一层
import axios from "axios" //导入axios
//创建axios 起个名$http
const $http = axios.create({
baseURL:'http://localhost:56405/',
timeout:7000 //默认超时时间 1000毫秒 等1秒
})
//vue 请求拦截
$http.interceptors.request.use(config=>{
//获取token 信息
let token = sessionStorage.getItem('token')
if(token){
//把请求带上头部信息 再请求api
config.headers.Authorization = 'Bearer ' +token
}
return config
})
//导出 将当前$http 供外部使用
export default $http
左侧菜单递归实现
<template>
<div class="page">
<el-container>
<el-header>八位用户权限管理系统 <el-button type="danger" @click="quit">退出</el-button>
</el-header>
<el-container>
<el-aside width="200px">
<menu-tree :menuData="this.menus"></menu-tree> //实现父给子组件传值
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
import MenuTree from "@/components/MenuTree.vue"
export default
{
name: 'aHome',
data () {
return {
menus: []
}
},
components: { MenuTree }, //显示子组件信息
methods: {
menu () {
var userId = sessionStorage.getItem('userId')
this.$http.get(`/api/Permission/GetPermission?userId=${userId}`).then(res => {
this.menus = res.data
console.log(res.data)
// res.data = this.option(o => {
// this.opens.push(o.Id)
// })
// console.log(res.data)
})
}
},
created () {
this.menu()
}
}
</script>
//子组件递归实现左侧菜单展示
<template>
<div class="page">
<el-menu default-active="2" class="el-menu-vertical-demo" :default-openeds=opens router background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
<template v-for="item in this.menuData">
<el-submenu v-if="item.menoDtos.length>0" :index="item.Id.toString()" :key="item.Id">
<template slot="title"> //循环一级导航 判断一级菜单是否大于零 是的话显示一级菜单
<i :class="item.PermissionIco"></i>
<span>{{item.PermissionName}}</span>
</template>
<MenuTree :menuData="item.menoDtos"></MenuTree> //循环调用此组件实现递归
</el-submenu>//如果一级导航的子节点有数据则显示
<el-menu-item v-else :key="item.menoDtos.Id" :index="item.PermissionUrl">
<template slot="title"> <i :class="item.PermissionIco"></i><span>{{item.PermissionName}}</span></template>
</el-menu-item>
</template>
</el-menu>
</div>
</template>
//组件接收父组件的传值
<script>
export default {
name: 'MenuTree',
data () {
return {
opens: ['1'] //默认index = 1为展开方式
}
}, props: ['menuData'], //接收父组件的数据
}
查看角色的权限以及给角色分配权限
//这里面只是script的methods方法的代码 页面布局直接element托组件
methods: {
upd (index, row) {
this.dialogFormVisible1 = true //关闭模态框
this.RoleName = row.RoleName
this.roleId = row.Id
this.$refs.tree.setCheckedKeys([]) //清空节点的信息 通过角色id查询权限的节点
this.$http.get(`/api/Role/GetRoleIdByPermissoins?roleId=${this.roleId}`).then(res => {
res.data.Data.forEach(e => {
let node = this.$refs.tree.getNode(e) //循环给节点赋值
//判断是否为叶子节点
if (node.isLeaf) {
this.$refs.tree.setChecked(node, true)
}
console.log(res.data.Data)
});
})
},
addPermission () {
let chk = this.$refs.tree.getCheckedKeys()
let half = this.$refs.tree.getHalfCheckedKeys() //这两个方法获取节点的id 如果只选择子节点 会自动勾选父节点
this.permissionIds = chk.concat(half) //这个方法把获取的两个节点信息拼接成数组
//分配权限
this.$http.post(`/api/Role/AddRolePermission? roleId=${this.roleId}&permissionIds=${this.permissionIds.toString()}`).then(res => {
if (res.data > 0) {
this.$message.success('权限设置成功')
this.dialogFormVisible1 = false
} else {
this.$message.error('权限设置失败')
}
})
},
//显示角色信息
load () {
this.$http.get(`/api/Role/GetRole`).then(res => {
this.tableData = res.data.Data
})
},
//通过角色id查询权限
getPermission () {
var userId = sessionStorage.getItem('userId')
this.$http.get(`/api/Permission/GetPermission?userId=${userId}`).then(res => {
this.data = res.data
console.log(res.data)
// res.data = this.option(o => {
// this.opens.push(o.Id)
// })
// console.log(res.data)
})
}
}
还有重要的一点就是登陆成功的时候向头部heads添加token码 然后给api授权访问
Login () {
this.$http.post(`/api/User/Login`, this.ruleForm).then(res => {
if (res.data.Code == 200) {
this.$message.success(res.data.Message)
sessionStorage.setItem('userId', res.data.Data.Id);
//获取请求头的信息
sessionStorage.setItem("token", res.headers.token); //这里是获取的token码
this.$router.push('system/role')
} else {
this.$message.error(res.data.Message)
}
})
}