新建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)
版本
- nodejs:20.9.0
- npm:10.1.0
- nestjs:10.0.0