如果您使用的是 graphql,您可以进行更改以适应下面的代码
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { GqlExecutionContext } from '@nestjs/graphql';
import { Role } from 'src/enums/role.enum';
import { ROLES_KEY } from '../auth';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles) {
return true;
}
const ctx = GqlExecutionContext.create(context);
const user = ctx.getContext().req.user;
return requiredRoles.some((role) => user.roles?.includes(role));
}
}
如果您不使用 graphql,请进行更改以适合下面的代码
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles) {
return true;
}
const { user } = context.switchToHttp().getRequest();
return requiredRoles.some((role) => user.roles?.includes(role));
}
}
然后在你的控制器中你可以做
@UseGuards(JwtAuthGuard, RolesGuard)
@hasRoles(UserRole.USER)
@Get()
findAll(): Observable<User[]> {
return this.userService.findAll();
}
最后,为了让这一切正常工作,像这样将全局守卫添加到您的 app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import {MongooseModule} from '@nestjs/mongoose';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
import configuration from 'src/config/configuration';
import { RolesGuard } from 'src/auth/auth';
import { UsersModule } from '../users/users.module';
import { AdminsModule } from 'src/admin/admins.module';
import { config } from 'dotenv';
import * as Joi from 'joi';
config();
@Module({
imports: [
// other modules
UsersModule,
// configuration module
ConfigModule.forRoot({
isGlobal: true,
cache: true,
load: [configuration],
expandVariables: true,
// validate stuff with Joi
validationSchema: Joi.object({
NODE_ENV: Joi.string()
.valid('development', 'production', 'test', 'provision')
.default('development'),
PORT: Joi.number().default(5000),
}),
validationOptions: {
// allow unknown keys (change to false to fail on unknown keys)
allowUnknown: true,
abortEarly: true,
},
}),
// connect to mongodb database
MongooseModule.forRoot(process.env.DB_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
}),
],
controllers: [AppController],
providers: [
AppService,
{
provide: 'APP_GUARD',
useClass: RolesGuard,
}
],
})
export class AppModule {}