身份验证
创建身份验证模块
nest g res auth
nest g res user
JWT 令牌
- 允许用户使用用户名/密码进行身份验证,返回 JWT 以用于后续调用受保护的 API 端点。 我们正在努力满足这一要求。 要完成它,我们需要编写发布 JWT 的代码。
- 创建基于有效 JWT 作为不记名令牌的存在而受到保护的 API 路由
yarn add @nestjs/jwt -S
auth/auth.service
import { Injectable } from '@nestjs/common';
import { CreateAuthDto } from './dto/create-auth.dto';
import { UpdateAuthDto } from './dto/update-auth.dto';
import { UserService } from './../user/user.service'
import { JwtService } from '@nestjs/jwt'
@Injectable()
export class AuthService {
constructor(private readonly userservice:UserService,private readonly jwtService:JwtService){}
async signIn(body){
const userInfo = await this.userservice.findOne(body.username)
console.log("authService",userInfo)
const payload = { sub: userInfo.id, username: userInfo.username };
return {
...userInfo,
access_token: await this.jwtService.signAsync(payload),
};
}
}
auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserModule } from './../user/user.module';
import { JwtModule } from '@nestjs/jwt';
import { AuthGuard } from './auth.guard'
import { APP_GUARD } from '@nestjs/core';
@Module({
imports: [
UserModule,
JwtModule.register({
global: true,
secret: '123456',
signOptions: { expiresIn: '6000s' },
}),
],
controllers: [AuthController],
providers: [AuthService,{
provide: APP_GUARD,
useClass: AuthGuard,
},],
})
export class AuthModule {}
auth.guard.ts
import {
CanActivate,
ExecutionContext,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { JwtService } from '@nestjs/jwt';
import { Request } from 'express';
import { IS_PUBLIC_KEY } from './public.guard';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private jwtService: JwtService, private reflector: Reflector) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) {
return true;
}
const request = context.switchToHttp().getRequest();
const token = this.extractTokenFromHeader(request);
if (!token) {
throw new UnauthorizedException();
}
try {
const payload = await this.jwtService.verifyAsync(token, {
secret: '123456',
});
request['user'] = payload;
} catch {
throw new UnauthorizedException();
}
return true;
}
private extractTokenFromHeader(request: Request): string | undefined {
const [type, token] = request.headers.authorization?.split(' ') ?? [];
return type === 'Bearer' ? token : undefined;
}
}
auth.controller.ts
import { Controller, Get, Post, Body, Patch, Param, Delete,UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { CreateAuthDto } from './dto/create-auth.dto';
import { UpdateAuthDto } from './dto/update-auth.dto';
import { AuthGuard } from './auth.guard'
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}
@Post('login')
login(@Body() body){
return this.authService.signIn(body)
}
@UseGuards(AuthGuard)
@Get('test')
getTest(){
return "鉴权通过"
}
}
自定义的 @Public() 装饰器 用于接口放行
public.guard.ts
import { SetMetadata } from '@nestjs/common';
export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
user模块
user.controller.ts
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { Public } from './../auth/public.guard'
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
@Public()
@Post('add')
create(@Body() user:CreateUserDto){
return this.userService.create(user)
}
}
user.service.ts
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity'
import { InjectRepository } from '@nestjs/typeorm'
import { Repository } from 'typeorm'
@Injectable()
export class UserService {
constructor(@InjectRepository(User) private readonly user:Repository<User>){}
create(createUserDto:CreateUserDto) {
console.log(createUserDto)
return this.user.save(createUserDto)
}
findOne(username:string){
return this.user.findOne({
where:{
username
}
})
}
}
user.module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { TypeOrmModule } from '@nestjs/typeorm'
import { User } from './entities/user.entity'
@Module({
imports:[
TypeOrmModule.forFeature([User])
],
controllers: [UserController],
providers: [UserService],
exports:[UserService],
})
export class UserModule {}