文章更多的是在于记录。有看不懂的评论
2.1 RBAC 0 https://juejin.cn/post/6844904109863075853#heading-3
最简单的用户、角色、权限模型。这里面又包含了2种:
依赖包
@nestjs/jwt
passport-jwt
这是用来对 token 进行处理的。他会在 request
jwt.strategy.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { IJwtData } from 'src/types/user';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private configService: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: configService.get('jwtSecret'),
});
}
validate(data: IJwtData) {
return data;
}
}
nest g res auth
auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { JwtModule } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { JwtStrategy } from 'src/strategy/jwt.strategy';
@Module({
imports: [
JwtModule.registerAsync({
inject: [ConfigService],
useFactory: (configService: ConfigService) => {
return {
secret: configService.get('jwtSecret'),
signOptions: {
expiresIn: '4h',
},
};
},
}),
],
controllers: [AuthController],
providers: [AuthService, JwtStrategy],
exports: [AuthService],
})
export class AuthModule {}
auth.service.ts
import { InjectRedis } from '@liaoliaots/nestjs-redis';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import Redis from 'ioredis';
import { IJwtData } from 'src/types/user';
@Injectable()
export class AuthService {
constructor(
@InjectRedis()
private readonly redis: Redis,
private jwtService: JwtService,
) {}
createToken(data: IJwtData) {
const token = this.jwtService.sign(data);
this.redis.hset('dialogua:token', token, 1);
return token;
}
async validate(token?: string) {
if (!token) throw new UnauthorizedException();
const exit = await this.redis.hexists('dialogua:token', token);
if (!exit) throw new UnauthorizedException();
}
}
auth.guard.ts
import { InjectRedis } from '@liaoliaots/nestjs-redis';
import { ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
import Redis from 'ioredis';
import { AuthGuard } from '@nestjs/passport';
import { ExtractJwt } from 'passport-jwt';
import { Reflector } from '@nestjs/core';
import { AuthService } from 'src/modules/auth/auth.service';
@Injectable()
export class RbacAuthGuard extends AuthGuard('jwt') {
constructor(
@InjectRedis() private readonly redis: Redis,
private authService: AuthService,
private reflector: Reflector,
) {
super();
}
async canActivate(context: ExecutionContext): Promise<any> {
const isPublic = this.reflector.get<boolean>('isPublic', context.getHandler());
if (isPublic) return true;
const request = context.switchToHttp().getRequest();
const token = ExtractJwt.fromAuthHeaderAsBearerToken()(request);
await this.authService.validate(token);
return super.canActivate(context);
}
}
app.module.ts
在这个文件里挂载是因为 guard 有依赖。 如果用 globalGuard. 无法自动注入依赖
import { RedisModule } from '@liaoliaots/nestjs-redis';
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { APP_GUARD } from '@nestjs/core';
import { JwtService } from '@nestjs/jwt';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import config from './config';
import { RbacAuthGuard } from './guards/auth.guard';
import modules from './modules';
@Module({
imports: [
...modules,
],
controllers: [AppController],
providers: [
// 这里。
{
provide: APP_GUARD,
useClass: RbacAuthGuard,
},
],
})
export class AppModule {}