跳到主要内容

grude 守卫

添加 strategy 策略

src/auth
├── auth.controller.ts
├── auth.module.ts
├── auth.service.ts
├── dto
│ ├── auth.dto.ts
│ └── index.ts
└── strategy
├── index.ts
└── jwt.strategy.ts

代码来自官网,修改高亮的地方。

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
  constructor(config: ConfigService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: config.get('JWT_SECRET'),
    });
  }

  async validate(payload: any) {
    return payload;
  }
}

moduleproviders 添加配置

import ...
import { JwtStrategy } from './strategy';

@Module({
  imports: [JwtModule.register({}), ConfigModule],
  controllers: [AuthController],
  providers: [AuthService, JwtStrategy],
})
export class AuthModule {}

使用 guard

创建 usermodulecontroller

nest g module user
nest g controller user --no-spec

user 添加 AuthGuard

// user.controller.ts
import { Controller, Get, Req, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { Request } from 'express';

@Controller('users')
export class UserController {
  constructor() {}
  @UseGuards(AuthGuard('jwt'))
  @Get('me')
  getMe(@Req() req: Request) {
    console.log({ user: req.user });
    return 'user info';
  }
}

发送请求

Authorization 的字段通过上一章 JWT 的 signToken 返回,并带入该字段中

GET /users/me HTTP/2
Host: localhost:3333
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEsImVtYWlsIjoidGVzdEBwcm90b25tYWlsLmNvbSIsImlhdCI6MTcwMjU0NjI2NSwiZXhwIjoxNzAyNTQ3MTY1fQ.d8pS1lDJ0r3fE4eUnRTx2n2pOLkK7L_11-f4zmDRDpQ

access_token 会通过 AuthGuard 解码,将得到以下数据。

// 控制台日志
{
user: {
sub: 1,
email: 'test@protonmail.com',
iat: 1702533250,
exp: 1702534150
}
}

优化:将 AuthGuard 抽离

新建 guard 文件夹,集中处理 AuthGuard 的逻辑

./src/auth/guard
├── index.ts
└── jwt.guard.ts
// jwt.guard.ts
import { AuthGuard } from '@nestjs/passport';

export class JwtGuard extends AuthGuard('jwt') {
constructor() {
super();
}
}
import { Controller, Get, Req, UseGuards } from '@nestjs/common';
import { Request } from 'express';
import { JwtGuard } from 'src/auth/guard';

@Controller('users')
export class UserController {
constructor() {}
@UseGuards(JwtGuard)
@Get('me')
getMe(@Req() req: Request) {
return 'user info2';
}
}