从零开始搭建nestjs项目-4 jwt鉴权

新建auth模块

nest g res auth

相关包:

 pnpm install --save @nestjs/jwt

为了保证服务完全模块化,所以在authService中生成token

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
    constructor(
        private jwtService: JwtService,
    ) { }

    // 获取token
    async getToken(payload: { [key: string]: number | string }) {
        return await this.jwtService.signAsync(payload)
    }

    // 解码token
    decode(token: string) {
        this.jwtService.decode(token)
    }
}

新建文件src/auth/contants.ts,用来存放密钥

export const jwtConstants = {
    secret: 'secret',//设置成随机字符串即可
};

// 无需鉴权的请求
export const ignoreUrlList = []

在auth.module.ts中

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './contants';

@Module({
  imports: [
    JwtModule.register({
      global: true,//全局注册
      secret: jwtConstants.secret,//私钥
      signOptions: { expiresIn: '7d' },//有效时间
    }),
  ],
  controllers: [AuthController],
  providers: [
    AuthService,
  ],
  exports: [AuthService],
})
export class AuthModule { }

利用守卫实现全局身份验证保护

新建守卫:nest g gu auth

import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { jwtConstants, ignoreUrlList } from './contants';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    private jwtService: JwtService
  ) { }
  async canActivate(context: ExecutionContext,): Promise<boolean> {
    const request = context.switchToHttp().getRequest();

    // 不用鉴权的url
    if (ignoreUrlList.includes(request.originalUrl)) {
      return true;
    }
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      const payload = await this.jwtService.verifyAsync(
        token,
        {
          secret: jwtConstants.secret
        }
      );
      // 💡 We're assigning the payload to the request object here
      // so that we can access it in our route handlers
      request['user'] = payload;
    } catch {
      throw new UnauthorizedException();
    }
    // console.log(token)
    return true;
  }


  private extractTokenFromHeader(request: Request): string | undefined {
    // @ts-ignore,此处按照自己的逻辑处理token,能拿到token即可
    const [token] = request.headers.authorization?.split(' ') ?? [];
    return token || undefined;
  }
}

全局启用身份验证在任意模块中添加以下代码,如auth.module.ts中

如果不想全局启用也可以在每个控制器顶部使用 @UseGuards() 装饰器

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './contants';
import { APP_GUARD } from '@nestjs/core';
import { AuthGuard } from './auth.guard';

@Module({
  imports: [
    JwtModule.register({
      global: true,//全局注册
      secret: jwtConstants.secret,//私钥
      signOptions: { expiresIn: '7d' },//有效时间
    }),
  ],
  controllers: [AuthController],
  providers: [
    AuthService,
    {
      provide: APP_GUARD,
      useClass: AuthGuard,
    },
  ],
  exports: [AuthService],
})
export class AuthModule { }

参考:身份验证 | NestJS 中文网 (nodejs.cn)

版本
  1. nodejs:20.9.0
  2. npm:10.1.0
  3. nestjs:10.0.0
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值