第一步:創(chuàng)建一個(gè)基礎(chǔ)項(xiàng)目
第二步:創(chuàng)建寫接口的模塊葬荷,建立moogodb數(shù)據(jù)庫連接涨共,寫添加與查詢接口
第三步:加入Swagger文檔
第四步:加入請求參數(shù)校驗(yàn)
-
注:不要關(guān)心注釋代碼,那是屬于后面功能的區(qū)域闯狱。因?yàn)殡S著代碼體量加大煞赢,功能不再明確,只需按照步驟并參考效果圖哄孤,把關(guān)鍵代碼寫入即可照筑,所以下只寫關(guān)鍵代碼,具體請看效果圖瘦陈。
項(xiàng)目地址
1 解決跨域問題
npm i cors
1.1 將cros
掛到全局中間件上
~/src/app.module.ts
import { Module, MiddlewareConsumer, NestModule } from '@nestjs/common';
// 跨域
import * as cors from 'cors';
// 定義中間件
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
// 解決跨域的問題的全局中間件
.apply(cors()).forRoutes('*')
// 驗(yàn)證token的全局中間件
// .apply(JwtExpiredMiddleware).forRoutes('*')
}
}
2 生成token凝危,校驗(yàn)token
2.3 生成token
// 生成token https://docs.nestjs.cn/9/security?id=jwt-%e5%8a%9f%e8%83%bd
import { JwtService } from '@nestjs/jwt';
// Swagger標(biāo)簽
@ApiTags('有Swagger文檔/開啟請求參數(shù)校驗(yàn)/Token')
// 請求方式:Post, 請求路徑:/user-copy/queryToken
@Post('queryToken')
// @Body() 裝飾器
async queryToken(@Body() body: userResponsesValidator) {
// 存儲(chǔ)參數(shù)到全局
this.globalParamsService.setParam('globalToken', body);
return {
// 對參數(shù)進(jìn)行簽名 生成token -- 正常來說肯定是要去庫里查這個(gè)賬號存不存在的 -- 由于是示例代碼 就不寫那么麻煩了 -- 不然忘了賬號又得再注冊一個(gè)
access_token: this.jwtService.sign({ user_name: body.user_name, password: body.password }),
};
}
2.2 創(chuàng)建token配置文件
npm i @nestjs/jwt jsonwebtoken
~/src/utils/tokenConfig.ts
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
// npm i jsonwebtoken
import * as jwt from 'jsonwebtoken';
interface JwtPayload {
exp: number;
// 其他 JWT 載荷屬性
}
// 定義token的簽名與超時(shí)時(shí)間
export const toeknData = {
secret: "tokenKey", // 密匙
expiresIn:"60s", // 超時(shí)時(shí)間60秒
}
@Injectable()
export class JwtExpiredMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
// 一般來說 可能會(huì)以正則去匹配白名單接口 - 大部分情況下,只會(huì)有極個(gè)別的接口會(huì)是白名單 - 由于是示例 就直接寫死了
// 如果 請求地址不為 /user-copy/findValidatorToken 則直接跳過
if (req.baseUrl !== '/user-copy/findValidatorToken') return next()
const token = req.headers.authorization?.split(' ')[1]; // 從請求頭中獲取 JWT
if (token) {
try {
// 解碼
const decoded = jwt.verify(token, toeknData.secret) as JwtPayload;
// 接收到JWT后執(zhí)行的邏輯
// 當(dāng)前時(shí)間戳
// const currentTime = Math.floor(Date.now() / 1000);
// decoded.exp 是解碼后的 JWT 中的過期時(shí)間晨逝,表示該令牌的有效期截止時(shí)間蛾默。
// decoded.iat 是解碼后的 JWT 中的簽發(fā)時(shí)間,表示該令牌的生成時(shí)間捉貌。
// 比較當(dāng)前時(shí)間是否已經(jīng)超出令牌有效期截至?xí)r間
// if (decoded.exp < currentTime) {
// // JWT 已經(jīng)超時(shí)
// // 執(zhí)行相應(yīng)的邏輯
// return res.send({ status: 99998, data: [], message: '登錄超時(shí)' });
// }
} catch (error) {
// JWT 驗(yàn)證失敗
// 執(zhí)行相應(yīng)的邏輯
return res.send({ status: 99998, data: error, message: '認(rèn)證失敗' });
}
} else {
// token認(rèn)證失敗
// 執(zhí)行相應(yīng)的邏輯
return res.send({ status: 99999, data: 'token in required', message: '認(rèn)證失敗' });
}
next();
}
}
2.3 引入并配置生成token規(guī)則支鸡, 并掛載到全局中間件
~/src/app.module.ts
// npm i @nestjs/jwt
// 生成token https://docs.nestjs.cn/9/security?id=jwt-%e5%8a%9f%e8%83%bd
import { JwtModule } from '@nestjs/jwt';
import { toeknData, JwtExpiredMiddleware } from './utils/tokenConfig'
// 配置生成的token
imports: [
JwtModule.register({
secret: toeknData.secret, // 是用于簽名和驗(yàn)證 JWT 的密鑰
signOptions: { expiresIn: toeknData.expiresIn }, // JWT 的過期時(shí)間。
}),
]
// 定義中間件
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
// 解決跨域的問題的全局中間件
.apply(cors()).forRoutes('*')
// 驗(yàn)證token的全局中間件
.apply(JwtExpiredMiddleware).forRoutes('*')
}
}