RBAC實現最基礎的許可權管理webapi+vue 一、確定關係表 //許可權管理表 這個表可以實現左側菜單的顯示 [Table("Permission")] public class Permission { [Key] public int Id { get; set; } public strin ...
一、確定關係表
//許可權管理表 這個表可以實現左側菜單的顯示
[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)
}
})
}