Nest.js 中间件
real-ip.middleware.ts
import {Injectable, NestMiddleware} from '@nestjs/common';
import {Request, Response, NextFunction} from 'express';
import {next} from "sucrase/dist/types/parser/tokenizer";
@Injectable()
export class RealIpMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log('RealIpMiddleware...');
next();
}
}
获取Ip
在默认情况下,Nest 中间件等同于Express 中间件,因此我们可以使用 Express 的 req.ip
属性来获取客户端的 IP 地址。
console.log(req.ip); // ::ffff:1
提示
::ffff:
前缀表示 IPv4 地址。1
表示本地客户端的 IP 地址。例如::ffff:127.0.0.1
这样我们就可以获取到客户端的 IP 地址了。(ps: 实际情况中部署到线上环境时,可能获取到的Ip地址是服务器的IP地址,遇到这种情况我们向下看)
代理服务器中获取IP
提示
使用了代理服务器时(ps: 反向代理),
req.ip
属性将返回代理服务器的 IP 地址,而不是客户端的 IP 地址。
解决这个问题我们可以通过安装 nestjs-real-ip 模块来解决。
import { RealIp } from 'nestjs-real-ip';
@Controller('/')
class TestController {
@Get('my-ip')
get(@RealIp() ip: string) {
return ip;
}
}
以上是 nestjs-real-ip 模块的用法,我们并未看到如何在中间件中使用它,因此我们可以查看该模块的源码。
src/index.ts
import * as requestIp from '@supercharge/request-ip';
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const RealIP = createParamDecorator((data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return requestIp.getClientIp(request);
});
export const RealIp = RealIP;
仿照上面的源码修改我们的中间件
real-ip.middleware.ts
import {Injectable, NestMiddleware} from '@nestjs/common';
import {Request, Response, NextFunction} from 'express';
import {next} from "sucrase/dist/types/parser/tokenizer";
+ import * as requestIp from '@supercharge/request-ip';
@Injectable()
export class RealIpMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
- console.log('RealIpMiddleware...');
+ const realIp = requestIp.getClientIp(req);
next();
}
}
测试一下,我们发现获取到的Ip地址是服务器的IP地址,而不是客户端的IP地址。
最终代码:
import {Injectable, NestMiddleware} from '@nestjs/common';
import {Request, Response, NextFunction} from 'express';
import * as requestIp from '@supercharge/request-ip';
@Injectable()
export class RealIpMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
const realIp = requestIp.getClientIp(req);
console.log(realIp);
next();
}
}