前言: 不同的认证方式虽然逻辑不同,但做的事情很类似
- 用户名密码登录就是从 request 的 body 里取出 username、password 来认证。
- jwt 是从 request 的 Authorization 的 header 取出 token 来认证。
依赖安装
npm install --save @nestjs/passport passport
实现用户名密码的认证,需要使用passport-local 的策略
npm install --save passport-local
npm install --save-dev @types/passport-local
1.创建 local.strategy.ts
import { UserService } from './user.service';
import { PassportStrategy } from '@nestjs/passport';
import { InjectRepository } from '@nestjs/typeorm';
import { StrategyOptions, Strategy, ExtractJwt } from 'passport-jwt';
import { User } from './entities/user.entity';
import { Repository } from 'typeorm';
import { UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
export class JwtStorage extends PassportStrategy(Strategy, 'jwt') {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository<User>, //需要注入,不能少
private readonly userService: UserService,
private readonly configService: ConfigService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: configService.get('JWT_SECRET'),
} as StrategyOptions);
}
async validate(user: User) {
//好像根本不要进行existUser这个判断, jwt只是根据传递的token信息在内部就进行了判断,并返回了user ,想了下还是需要,万一用户被删除了,你找不到,但是token这时候还是表示删除的用户,这个时候就有问题
const existUser = await this.userService.getUser(user);
if (!existUser) {
throw new UnauthorizedException('当前用户不存在');
}
return existUser;
//return user
}
}
2.jwt.strategy.ts中
import { UserService } from './user.service';
import { PassportStrategy } from '@nestjs/passport';
import { InjectRepository } from '@nestjs/typeorm';
import { StrategyOptions, Strategy, ExtractJwt } from 'passport-jwt';
import { User } from './entities/user.entity';
import { Repository } from 'typeorm';
import { UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
export class JwtStorage extends PassportStrategy(Strategy, 'jwt') {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository<User>, //需要注入,不能少
private readonly userService: UserService,
private readonly configService: ConfigService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: configService.get('JWT_SECRET'),
} as StrategyOptions);
}
async validate(user: User) {
//好像根本不要进行existUser这个判断, jwt只是根据传递的token信息在内部就进行了判断,并返回了user ,想了下还是需要,万一用户被删除了,你找不到,但是token这时候还是表示删除的用户,这个时候就有问题
const existUser = await this.userService.getUser(user);
if (!existUser) {
throw new UnauthorizedException('当前用户不存在');
}
return existUser;
//return user
}
}
在 use.module中进行注册
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';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { LocalStorage } from './local.strategy';
import { JwtStorage } from './jwt.strategy';
import { ConfigModule, ConfigService } from '@nestjs/config';
const jwtModule = JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
secret: configService.get<string>('JWT_SECRET'),
signOptions: { expiresIn: '12h' },
}),
inject: [ConfigService],
});
@Module({
imports: [TypeOrmModule.forFeature([User]), PassportModule, jwtModule],
controllers: [UserController],
providers: [UserService, LocalStorage, JwtStorage, ConfigService],
exports: [jwtModule],
})
export class UserModule {}
4.使用
@Controller('user')
export class UserController {
constructor(
private readonly userService: UserService,
private readonly jwtService: JwtService,
) {}
@Post('/register')
register(@Body() createUserDto: CreateUserDto) {
return this.userService.create(createUserDto);
}
createToken(user: Partial<User>) {
return this.jwtService.sign(user);
}
@Post('login')
@UseGuards(AuthGuard('local')) //这里使用local策略,返回token
//login这里不用获取用户 username and password ,应该是直接在AuthGuard中间件中获取
async login(@Req() req) {
const user = req.user;
const token = this.createToken({
id: user.id,
username: user.username,
});
//查询user,把user权限返回,[admin =99 ,visiter = 0]
const existUser = await this.userService.getUser({ id: user.id });
return {
data: {
token,
user: {
id: existUser.data.id,
userName: existUser.data.username,
role: existUser.data.role,
},
},
};
}
@UseGuards(AuthGuard('jwt'))
@Get()
findAll(@Body() params) {
return this.userService.findAll(params);
}
@UseGuards(AuthGuard('jwt'))
@Get('/userInfo')
findOne(@Body() params) {
return this.userService.getUser(params);
}
}
- THE END -
最后修改:2024年6月28日
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://www.puxiaoshuai.top/?p=152