nestjs 用户注册登录验证模块
时间: 2023-07-21 13:28:11 浏览: 159
在 NestJS 中,可以使用 Passport 和 JWT 来实现用户注册、登录和验证。以下是一个简单的示例,演示如何使用 NestJS、Passport 和 JWT 实现用户认证。
1. 安装必要的依赖项
```
npm install --save @nestjs/passport passport passport-jwt bcryptjs
```
2. 创建用户模型
在数据库中创建一个用户模型,包含用户名和密码等信息。
```typescript
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
@Column()
password: string;
}
```
3. 创建认证模块
创建一个认证模块,包含 Passport 和 JWT 的配置和逻辑。
```typescript
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { JwtStrategy } from './jwt.strategy';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserModule } from '../user/user.module';
@Module({
imports: [
UserModule,
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.register({
secret: 'mysecret',
signOptions: { expiresIn: '1d' },
}),
],
providers: [AuthService, JwtStrategy],
controllers: [AuthController],
exports: [PassportModule, AuthService],
})
export class AuthModule {}
```
在上面的代码中,我们将 `JwtModule` 注册为全局模块,指定了 JWT 密钥和过期时间。我们还将 `PassportModule` 注册为全局模块,并使用 `JwtStrategy` 来验证 JWT 令牌。`AuthService` 和 `AuthController` 分别处理认证逻辑和路由。
4. 创建 JWT 策略
创建一个 JWT 策略,用于验证 JWT 令牌。
```typescript
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthService } from './auth.service';
import { User } from '../user/user.entity';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'mysecret',
});
}
async validate(payload: any): Promise<User> {
const user = await this.authService.validateUser(payload);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
```
在上面的代码中,我们使用 `PassportStrategy` 基类创建一个新的 JWT 策略。我们还指定了从请求头中提取 JWT 令牌的方式,并指定了 JWT 密钥。`validate()` 方法用于验证 JWT 令牌,并返回用户对象。如果无法验证令牌,则抛出 `UnauthorizedException` 异常。
5. 创建认证服务
创建一个认证服务,用于处理用户认证和 JWT 生成。
```typescript
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { compare } from 'bcryptjs';
import { User } from '../user/user.entity';
import { UserService } from '../user/user.service';
@Injectable()
export class AuthService {
constructor(
private userService: UserService,
private jwtService: JwtService,
) {}
async validateUser(username: string, password: string): Promise<User> {
const user = await this.userService.findOneByUsername(username);
if (user && (await compare(password, user.password))) {
const { password, ...result } = user;
return result;
}
return null;
}
async login(user: User) {
const payload = { username: user.username, sub: user.id };
return {
access_token: this.jwtService.sign(payload),
};
}
}
```
在上面的代码中,我们创建了一个 `AuthService` 类,包含了验证用户和生成 JWT 令牌的逻辑。`validateUser()` 方法用于验证用户的凭据,并返回用户对象。如果验证成功,则返回用户对象,否则返回 null。`login()` 方法用于生成 JWT 令牌,并返回包含令牌的对象。
6. 创建认证控制器
创建一个认证控制器,用于处理用户注册、登录和验证等请求。
```typescript
import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { LocalAuthGuard } from './local-auth.guard';
import { User } from '../user/user.entity';
@Controller()
export class AuthController {
constructor(private authService: AuthService) {}
@Post('register')
async register(@Request() req) {
const user = await this.authService.register(req.body);
return { message: 'User registered successfully.', user };
}
@UseGuards(LocalAuthGuard)
@Post('login')
async login(@Request() req) {
return this.authService.login(req.user as User);
}
@UseGuards(AuthGuard('jwt'))
@Post('profile')
async getProfile(@Request() req) {
return req.user;
}
}
```
在上面的代码中,我们创建了一个 `AuthController` 类,包含了注册、登录和验证等请求的处理逻辑。`register()` 方法用于注册用户,并返回包含用户对象的对象。`login()` 方法用于登录用户,并返回包含 JWT 令牌的对象。`getProfile()` 方法用于返回当前用户的对象,需要验证 JWT 令牌。
7. 创建本地认证守卫
创建一个本地认证守卫,用于验证用户名和密码。
```typescript
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
```
在上面的代码中,我们创建了一个 `LocalAuthGuard` 类,继承自 `AuthGuard` 类。这个守卫使用 `local` 策略来验证用户名和密码。
8. 创建用户模块
创建一个用户模块,用于管理用户和提供服务。
```typescript
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UserService } from './user.service';
@Module({
imports: [TypeOrmModule.forFeature([User])],
providers: [UserService],
exports: [UserService],
})
export class UserModule {}
```
在上面的代码中,我们创建了一个 `UserModule` 类,包含了用户模型和服务。我们还将 `UserService` 导出,以便其他模块可以使用它。
9. 配置 Passport
在 `main.ts` 文件中配置 Passport 和全局中间件。
```typescript
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
app.use(passport.initialize());
app.use(passport.session());
await app.listen(3000);
}
bootstrap();
```
在上面的代码中,我们将全局中间件 `ValidationPipe` 注册到应用程序中,并使用 `passport.initialize()` 和 `passport.session()` 配置 Passport。
现在,我们已经完成了 NestJS、Passport 和 JWT 的集成。可以使用以下路由进行测试:
- `POST /register`: 注册一个新用户。
- `POST /login`: 登录用户,并返回 JWT 令牌。
- `POST /profile`: 获取当前用户的信息。需要在请求头中添加 `Authorization: Bearer <JWT>`。
注意:上面的代码只是一个示例,需要根据实际情况进行修改和调整。
阅读全文