在接口调用中,我们经常会遇到需要用户登录的情况,这时候一般比较常用的就是 jwt 了。在 nest 中,可以使用 nest 提供的 jwt 模块来实现 jwt 的功能。来看看如何使用吧。
安装
npm install @nestjs/jwt
引入 JwtModule 模块
我们需要在 app.module.ts 中引入 JwtModule 模块
register 方法接收一个对象,对象中有两个属性,一个是 secret,一个是 signOptions。secret 是用来加密的,signOptions 是用来设置 token 的过期时间的。在这里我们设置了 7 天过期。
import { Module } from '@nestjs/common'
import { JwtModule } from '@nestjs/jwt'
import { AppController } from './app.controller'
import { AppService } from './app.service'
@Module({
imports: [
JwtModule.register({
secret: 'water',
signOptions: {
expiresIn: '7d'
}
})
],
controllers: [AppController],
providers: [AppService]
})
export class AppModule {}
使用 JwtService 生成token
import { Controller, Get, Post, Body, UseGuards } from '@nestjs/common'
import { AppService } from './app.service'
import { JwtService } from '@nestjs/jwt'
@Controller()
export class AppController {
constructor(private readonly appService: AppService, private readonly jwtService: JwtService) {}
@Get()
getHello(): string {
return this.appService.getHello()
}
@Post('login')
login(@Body() body) {
const token = this.jwtService.sign({
username: body.username,
password: body.password
},{ secret: 'water' })// secret: 'water' 密钥
return {
token
}
}
}
使用验证 token
在接口调用的过程中,带上上面生成的 token,然后在控制器中使用 jwtService 的 verify 方法来验证 token
用 UseGuards 装饰器来使用 jwt 的验证,AuthGuard 的参数是 jwt,表示使用 jwt 的验证。然后在 getProfile 方法中使用 @Request() req 来获取用户信息。
import { Controller, Get, Post, Body, UseGuards } from '@nestjs/common'
import { AppService } from './app.service'
import { JwtService } from '@nestjs/jwt'
import { AuthGuard } from './auth/auth.guard';
@Controller()
export class AppController {
constructor(private readonly appService: AppService, private readonly jwtService: JwtService) {}
@Get()
getHello(): string {
return this.appService.getHello()
}
@Post('login')
login(@Body() body) {
const token = this.jwtService.sign({
username: body.username,
password: body.password
})
return {
token
}
}
@Get('profile')
getProfile(@Req() request) {
const authHeader = request.headers.authorization;
if(authHeader){
try {
const user = this.jwtService.verify(authHeader)
return user;
} catch (error) {
return '请登录';
}
}
return '请登录';
}
@Get('profile2')
@UseGuards(AuthGuard)
getProfile2(@Req() request) {
console.log(request.user)
return request.user;
}
}
AuthGuard ./auth/auth.guard 类的源码
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private readonly jwtService: JwtService) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest()
const authHeader = request.headers.authorization
if (!authHeader) {
request.user = null
}
try {
const user = this.jwtService.verify(authHeader)
request.user = user
return true
} catch (error) {
request.user = null
}
}
}
app.module.ts 引入 AuthGuard
providers: [...,AuthGuard],