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;
}
}
在 module 中 providers 添加配置
import ...
import { JwtStrategy } from './strategy';
@Module({
imports: [JwtModule.register({}), ConfigModule],
controllers: [AuthController],
providers: [AuthService, JwtStrategy],
})
export class AuthModule {}
使用 guard
创建 user 的 module 与 controller
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';
}
}