Nest 初始化 和 权限分级
初始化
- 上来赋值 3 个用户 3 个角色 3 个权限
新建一个 user.init.service.ts
- 绑定到 model 上面
ts
import { Inject, Injectable } from "@nestjs/common";
// 引入数据库模块
import { PrismadbService } from "../../prisma/prisma.service";
// 引入redis模块
import { RedisService } from "../../redis/redis.service";
// 引入异常模块
import { GlobalCheckException } from "../../../common/globalcheck.exception";
// 引入md5
// 引入加密模块
import * as crypto from "crypto";
export class UserInitService {
@Inject(RedisService)
private readonly redisService: RedisService;
@Inject(PrismadbService)
private readonly prismaService: PrismadbService;
md5(password) {
const hash = crypto.createHash("md5");
hash.update(password);
const passwordhash = hash.digest("hex");
return passwordhash;
}
// 初始化
async init() {
// 初始化数据
const users = [
{
username: "admin",
password: this.md5("123456"),
email: "2993222085@qq.com",
phone_number: "19000000001",
nick_name: "超级管理员",
head_pic: "https://file.jsopy.com/IMAGES/avatarsmoke.jpg",
is_frozen: 1,
is_admin: 2,
},
{
username: "admin2",
password: this.md5("123456"),
email: "2993222086@qq.com",
phone_number: "19000000002",
nick_name: "频道管理员",
head_pic: "https://file.jsopy.com/IMAGES/avatar.jpg",
is_frozen: 1,
is_admin: 1,
},
{
username: "admin3",
password: this.md5("123456"),
email: "2993222087@qq.com",
phone_number: "19000000003",
nick_name: "游客",
head_pic: "https://file.jsopy.com/IMAGES/avatarmoney.jpg",
is_frozen: 1,
is_admin: 1,
},
];
// 角色
const roles = [
{
name: "超级管理员",
},
{
name: "频道管理员",
},
{
name: "游客",
},
];
// 权限
const permissions = [
{
code: "*",
description: "超级管理员",
},
{
code: "user",
description: "user管理员",
},
{
code: "testproject",
description: "testproject管理员",
},
];
// 测试先创建用户
const userresult = await this.createUser(users);
// 创建角色
const rolesresult = await this.create_roles(roles);
// 创建 权限
const permissionresult = await this.create_permission(permissions);
// 用户角色关系
const userRolesResult = await this.createUserRoles();
// 角色 和 权限关系
const rolePermissionResult = await this.createRolePermissions();
return true;
}
// 1. 创建用户
async createUser(users: any) {
//1 . 查询以前有没有用户
const oldnum = await this.createUser_findold(users);
if (oldnum == 0) {
// 存入
const result = await this.prismaService.users.createMany({
data: users,
});
return result;
} else {
throw new GlobalCheckException("用户已存在");
}
}
// 1.1 创建用户查询
async createUser_findold(users: any): Promise<number> {
// 查询有没有用户
const result = await this.prismaService.users.findMany({
where: {
email: {
in: users.map((item: any) => item.email),
},
},
});
// 返回结果
if (result) {
return result.length;
} else {
return 0;
}
}
// 2 创建角色
async create_roles(roles: any) {
const result = await this.createRoles_findold(roles);
if (result == 0) {
const result = await this.prismaService.roles.createMany({
data: roles,
});
return result;
} else {
return null;
}
}
// 2.1 读取角色
async createRoles_findold(roles: any) {
const result = await this.prismaService.roles.findMany({
where: {
name: {
in: roles.map((item: any) => item.name),
},
},
});
if (result) {
return result.length;
} else {
return 0;
}
}
// 3. 创建权限
async create_permission(permissions: any) {
const result = await this.create_permission_findold(permissions);
if (result == 0) {
const result = await this.prismaService.permissions.createMany({
data: permissions,
});
return result;
} else {
return null;
}
}
// 3.1 读取权限
async create_permission_findold(permissions: any) {
const result = await this.prismaService.permissions.findMany({
where: {
code: {
in: permissions.map((item: any) => item.code),
},
},
});
if (result == permissions.length) {
return result.length;
} else {
return 0;
}
}
// 4. 创建用户角色
async createUserRoles() {
const users = await this.prismaService.users.findMany();
const roles = await this.prismaService.roles.findMany();
// 查询老的
const result = await this.createUserRoles_findold(users);
if (result) {
const result = await this.prismaService.user_roles.createMany({
data: users.map((item: any, index: number) => {
return {
user_id: item.id,
role_id: roles[index].id,
};
}),
});
return true;
} else {
return null;
}
}
// 4.1 查询一下 以前有没有
async createUserRoles_findold(users: any) {
const result = await this.prismaService.user_roles.findFirst({
where: {
user_id: {
in: users.map((item: any) => item.id),
},
},
});
if (result) {
return false;
} else {
return true;
}
}
// 5. 角色权限
async createRolePermissions() {
const roles = await this.prismaService.roles.findMany();
const permissions = await this.prismaService.permissions.findMany();
const result = await this.createRolePermissions_findold(roles);
if (result) {
// 超级管理员
await this.prismaService.role_permissions.createMany({
data: roles.map((item: any, index: number) => {
return {
role_id: roles[0].id,
permission_id: permissions[index].id,
};
}),
});
// 频道管理员
await this.prismaService.role_permissions.create({
data: {
role_id: roles[1].id,
permission_id: permissions[1].id,
},
});
// 游客
await this.prismaService.role_permissions.create({
data: {
role_id: roles[2].id,
permission_id: permissions[2].id,
},
});
return true;
}
}
// 5.1 查询以下老的
async createRolePermissions_findold(roles: any) {
const result = await this.prismaService.role_permissions.findFirst({
where: {
role_id: {
in: roles.map((item: any) => item.id),
},
},
});
if (result) {
return false;
} else {
return true;
}
}
}user.controller.ts
- 新建 init 接口
ts
// 初始化
@Post('init')
async init() {
const result = await this.userInitService.init();
if (result) {
return {
code: 200,
message: '初始化成功',
};
} else {
return {
code: 403,
message: '初始化失败',
};
}
}利用 RBAC 进行权限鉴别
新建一个权限守卫 roles.guard.ts
ts
import {
Injectable,
CanActivate,
ExecutionContext,
Inject,
} from "@nestjs/common";
import { Observable } from "rxjs";
import { Reflector } from "@nestjs/core";
import { PrismadbService } from "../moduels/prisma/prisma.service";
import { RedisService } from "../moduels/redis/redis.service";
import { ConfigService } from "@nestjs/config";
// 抛出异常
import { GlobalGuardException } from "../common/globalguard.exception";
@Injectable()
export class RolesGuard implements CanActivate {
@Inject()
private readonly redisService: RedisService;
@Inject()
private readonly prismadbService: PrismadbService;
@Inject(Reflector)
private readonly reflector: Reflector;
@Inject()
private configService: ConfigService;
async canActivate(context: ExecutionContext): Promise<any> {
// 白名单就放行
let isPublic = false;
//权限验证
const request = context.switchToHttp().getRequest();
// 白名单
const whiteList = this.configService.get("PERMISSION_WHITELIST");
// 如果没有就放行
if (whiteList == "" || whiteList.includes(request.url)) {
isPublic = true;
}
if (isPublic) {
return true;
} else {
// 获取到设定的权限
const permissions = this.reflector.getAllAndOverride<string[]>(
"permissions",
[context.getHandler(), context.getClass()]
);
// 通过userId获取到用户角色
// 权限验证 全局守卫会给你userId
const request = context.switchToHttp().getRequest();
// 1. 先去redis中查找 2. 找不到就走数据库 3. 数据库取出来存到redis中
let userPermissionsName: any = await this.redisService.getlist(
`userId_${request.userId}_roles`
);
if (!userPermissionsName || userPermissionsName.length === 0) {
console.log("进数据库来了");
// 1. 查出这个用户拥有的角色ID
const RoleId: any = await this.prismadbService.user_roles.findMany({
where: {
user_id: request.userId,
},
select: {
role_id: true,
},
});
// 2. 查询出这个角色拥有的权限ID
const userPermissionsId: any =
await this.prismadbService.role_permissions.findMany({
where: {
role_id: {
in: RoleId.map((item) => item.role_id),
},
},
select: {
permission_id: true,
},
});
// 3. 查出这个权限ID对应的权限
let userPermissions = await this.prismadbService.permissions.findMany({
where: {
id: {
in: userPermissionsId.map((item) => item.permission_id),
},
},
select: {
code: true,
},
});
userPermissionsName = userPermissions.map((item) => item.code);
console.log("最后结果");
console.log(userPermissionsName);
// 3. 存到redis中
this.redisService.setlist(
`userId_${request.userId}_roles`,
userPermissionsName,
60 * 30
); // 过期时间30分钟
}
// 判断返回
const result = permissions.some((item) => {
return userPermissionsName.includes(item);
});
if (result) {
return true;
} else {
throw new GlobalGuardException("权限不足");
}
}
}
}接口里面使用
比如 user 模块下面 增加一个 权限守卫, 这个相当于只有权限是, *或者 user 能访问 到这个接口
testproject 访问不了这个模块
ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
UseGuards,
Req,
SetMetadata,
} from "@nestjs/common";
import { UserRegisterService } from "./services/user.register.service";
import { UserSendEmailService } from "./services/user.sendEmail.service";
import { UserLoginService } from "./services/user.login.service";
import { UserInitService } from "./services/user.init.service";
import { RegisterUserDto } from "./dto/register-user.dto";
import { AuthGuard } from "@nestjs/passport";
import { RolesGuard } from "../../common/roles.guard";
@Controller("user")
@SetMetadata("permissions", ["*", "user"])
@UseGuards(RolesGuard)
export class UserController {
constructor(
private readonly userRegisterService: UserRegisterService,
private readonly userSendEmailService: UserSendEmailService,
private readonly userLoginService: UserLoginService,
private readonly userInitService: UserInitService
) {}
// 初始化
@Post("init")
async init() {
const result = await this.userInitService.init();
if (result) {
return {
code: 200,
message: "初始化成功",
};
} else {
return {
code: 403,
message: "初始化失败",
};
}
}
// 测试验证
@Get("testroles")
async testroles() {
return {
code: 200,
message: "验证成功",
data: "通过验证",
};
}
}