莆田建站培訓(xùn)seo實(shí)戰(zhàn)密碼第四版pdf
使用 Nest.js 開發(fā)項(xiàng)目時(shí),處理身份驗(yàn)證和授權(quán)是常見的需求,可以采用以下架構(gòu)和實(shí)現(xiàn)方式。
架構(gòu)
-
用戶認(rèn)證模塊 (Auth Module):
- 服務(wù) (Service): 處理用戶登錄邏輯,生成 JWT(JSON Web Token),以及驗(yàn)證 token。
- 控制器 (Controller): 提供登錄接口,處理來自客戶端的請求。
- 中間件/守衛(wèi) (Guards): 在需要保護(hù)的路由中,驗(yàn)證請求頭中的 token,決定是否放行。
-
JWT 模塊:
- 利用 Nest.js 提供的 JWT 模塊來簡化 token 的生成與驗(yàn)證。
-
數(shù)據(jù)庫模塊:
- 用于存儲和查詢用戶信息,可能使用 TypeORM 或 Mongoose 等庫來操作數(shù)據(jù)庫。
實(shí)現(xiàn)步驟
1. 安裝所需的依賴
在項(xiàng)目中安裝以下依賴:
npm install @nestjs/jwt @nestjs/passport passport passport-jwt bcrypt
2. 創(chuàng)建 Auth Module
生成 Auth 模塊:
nest g module auth
nest g controller auth
nest g service auth
3. 實(shí)現(xiàn)用戶登錄邏輯
在 auth.service.ts
中實(shí)現(xiàn)用戶登錄和 token 生成邏輯:
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UserService } from '../user/user.service'; // 假設(shè)你有一個(gè)用戶服務(wù)
import { User } from '../user/user.entity'; // 假設(shè)你有一個(gè)用戶實(shí)體
import * as bcrypt from 'bcrypt';@Injectable()
export class AuthService {constructor(private userService: UserService,private jwtService: JwtService,) {}async login(username: string, password: string): Promise<string> {const user: User = await this.userService.findByUsername(username);if (user && await bcrypt.compare(password, user.password)) {const payload = { username: user.username, sub: user.id };return this.jwtService.sign(payload);}throw new Error('Invalid credentials');}
}
4. 創(chuàng)建登錄接口
在 auth.controller.ts
中添加登錄接口:
import { Controller, Post, Body } from '@nestjs/common';
import { AuthService } from './auth.service';@Controller('auth')
export class AuthController {constructor(private authService: AuthService) {}@Post('login')async login(@Body() loginDto: { username: string; password: string }) {return this.authService.login(loginDto.username, loginDto.password);}
}
5. 設(shè)置 JWT 模塊
在 auth.module.ts
中配置 JWT 模塊:
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { UserService } from '../user/user.service'; // 引入用戶服務(wù)@Module({imports: [JwtModule.register({secret: 'your_secret_key', // 應(yīng)該放在環(huán)境變量中signOptions: { expiresIn: '60s' }, // token 過期時(shí)間}),],controllers: [AuthController],providers: [AuthService, UserService],
})
export class AuthModule {}
6. 創(chuàng)建 JWT 校驗(yàn)守衛(wèi)
創(chuàng)建一個(gè)守衛(wèi)來驗(yàn)證 token,在 auth.guard.ts
中實(shí)現(xiàn):
import { Injectable, ExecutionContext, UnauthorizedException } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {handleRequest(err, user) {if (err || !user) {throw new UnauthorizedException();}return user;}
}
7. 設(shè)置 JWT 策略
在 auth.strategy.ts
中定義 JWT 策略:
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { UserService } from '../user/user.service'; // 引入用戶服務(wù)
import { JwtPayload } from './jwt.payload'; // 定義 payload 接口@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {constructor(private userService: UserService) {super({jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),ignoreExpiration: false,secretOrKey: 'your_secret_key', // 應(yīng)該放在環(huán)境變量中});}async validate(payload: JwtPayload) {return this.userService.findById(payload.sub); // 根據(jù) payload.sub 查找用戶}
}
8. 保護(hù)路由
在需要保護(hù)的控制器中使用守衛(wèi):
import { Controller, Get, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth.guard';@Controller('protected')
export class ProtectedController {@UseGuards(JwtAuthGuard)@Get()getProtectedResource() {return 'This is a protected resource';}
}
總結(jié)
通過以上步驟,可以實(shí)現(xiàn)一個(gè)簡單的用戶登錄和 JWT 身份驗(yàn)證系統(tǒng)。用戶登錄時(shí)會生成 token,而在需要保護(hù)的接口中,通過中間件校驗(yàn) token 的有效性,以決定是否放行請求。建議把 secret key 存放在環(huán)境變量中,以增強(qiáng)安全性。