Nestjs ( 三 ) 认证(Authentication)

234 阅读1分钟

image.png

地址 :

docs.nestjs.cn/9/security?…

理论官网都有 仅记录实现 毕竟技术要为业务服务的
npm install --save @nestjs/passport passport passport-local
npm install --save-dev @types/passport-local
nest g mo auth
nest g co auth
nest g s auth

image.png

auth.module.ts

/*
 * @Author: zhang_gen_yuan
 * @Date: 2023-05-10 20:36:03
 * @LastEditTime: 2023-05-10 22:58:37
 * @Descripttion: aa
 */
import { Module,forwardRef } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UserModule } from '../user/user.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';
import { JwtStrategy } from './jwt.strategy';


@Module({
  imports: [
    UserModule,
    /*
     * 默认策略  我们在 @AuthGuard() 装饰器中传递策略的名称
     * 传递名称可以消除我们链接到的实现的歧义
     * */
    PassportModule.register({defaultStrategy:'jwt'}),
    JwtModule.register({
      secret: jwtConstants.secret
    }),
  ],
  providers: [AuthService, LocalStrategy,JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}

auth.service.ts

import { Injectable } from '@nestjs/common';
import { UserService } from '../user/user.service';
import { JwtService } from '@nestjs/jwt';
import { jwtConstants } from "./constants";

@Injectable()
export class AuthService {
  constructor(private readonly usersService: UserService, private readonly jwtService: JwtService) { }
  async validateUser(payload: any): Promise<any> {
    return {};
  }
  async login(user: { username: string; password: string; }):Promise<any> {
    const loginInfo:any = await this.usersService.findOne(user.username)
    if(!loginInfo) return "暂无此用户"
    if(loginInfo && loginInfo.password !== user.password){
      return "密码错误"
    }
    if(loginInfo && loginInfo.password === user.password){
      const payload = {userId:loginInfo.id,username:loginInfo.username,role:loginInfo.role,date:Date.now()}
      return {
        ...loginInfo,
        access_token: this.jwtService.sign(payload,{privateKey:jwtConstants.secret,expiresIn: '24h'})
      }
    }
  }
}

constants.ts

从官网粘贴过来的 生产可换自己的秘钥

export const jwtConstants = {
  secret: 'secretKey',
};

jwt.strategy

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { jwtConstants } from './constants';
import { AuthService } from './auth.service';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService:AuthService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload: any) {
    const user = await this.authService.validateUser(payload);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

local-auth.guard

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}

local.strategy

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.login({username, password});
    return user;
  }
}

使用

@UseGuards(AuthGuard("jwt"))

获取

image.png

过期 401

image.png