nestjs 中 JWT 鉴权登录
读者来稿 · song-shao与 batype 的 AI 分身对话整理
在 NestJS 中使用 JWT(JSON Web Token)进行鉴权和登录是一个非常常见的做法。下面是一个示例,展示如何实现 JWT 鉴权和登录。
前置条件#
确保你已经安装了 NestJS,并且你的项目中已经安装了以下依赖:
@nestjs/jwt@nestjs/passportpassportpassport-jwtbcryptjs(可选,用于哈希密码)
你可以使用以下命令安装这些依赖:
npm install @nestjs/jwt @nestjs/passport passport passport-jwt bcryptjs
步骤#
1. 创建 AuthModule#
生成一个新的模块,用于处理身份验证。
nest generate module auth
2. 创建 AuthService#
在 AuthModule 中创建一个 AuthService,负责处理用户验证和 JWT 生成。
nest generate service auth
在生成的 auth.service.ts 中:
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcryptjs';
@Injectable()
export class AuthService {
constructor(private readonly jwtService: JwtService) {}
async validateUser(username: string, pass: string): Promise<any> {
// 这里通常调用用户服务从数据库获取用户
const user = { username: 'test', password: await bcrypt.hash('password', 10) }; // 示例用户
const isPasswordMatching = await bcrypt.compare(pass, user.password);
if (user && isPasswordMatching) {
const { password, ...result } = user;
return result;
}
return null;
}
async login(user: any) {
const payload = { username: user.username, sub: user.userId };
return {
access_token: this.jwtService.sign(payload),
};
}
}
3. 设置 JWT Strategy#
创建一个 JwtStrategy,用于提取和验证 JWT。
nest generate class auth/jwt.strategy
在 jwt.strategy.ts 中:
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: 'your_jwt_secret_key', // 请确保使用环境变量存储密钥
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
4. 配置 AuthModule#
在 auth.module.ts 中配置模块和服务:
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
@Module({
imports: [
PassportModule,
JwtModule.register({
secret: 'your_jwt_secret_key', // 请确保使用环境变量存储密钥
signOptions: { expiresIn: '60m' },
}),
],
providers: [AuthService, JwtStrategy],
exports: [AuthService],
})
export class AuthModule {}
5. 实现 AuthController#
创建一个控制器来处理登录请求。
nest generate controller auth
在 auth.controller.ts 中:
import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthGuard } from '@nestjs/passport';
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}
@UseGuards(AuthGuard('local'))
@Post('login')
async login(@Request() req) {
return this.authService.login(req.user);
}
}
6. 使用 Guards 保护路由#
在需要保护的路由上使用 AuthGuard:
import { Controller, Get, UseGuards, Request } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Controller('profile')
export class ProfileController {
@UseGuards(AuthGuard('jwt'))
@Get()
getProfile(@Request() req) {
return req.user;
}
}
这样,你已经设置了一个基础的 JWT 鉴权系统。 请注意,密钥应存储在环境变量中,并且不要在生产中硬编码。
此外,确保根据你的应用需求修改用户验证逻辑(例如从数据库中查询用户)。
相关文章
- nestjs 使用nodemailer 编写邮件发送模块服务
NestJS邮件发送指南:使用Nodemailer和@nestjs-modules/mailer。安装必要包,创建邮件模块和服务,配置SMTP,发送邮件。确保SMTP配置正确,使用环境变量保护敏感信息。
- nestjs 配置swagger
NestJS项目中使用Swagger生成API文档的详细指南,包括安装依赖、配置Swagger、设置基础信息、认证、生成文档、添加Swagger装饰器等步骤,以及如何访问和使用Swagger文档。