the*_*eva 3 node.js express stripe-payments typescript nestjs
我需要从Nest.js应用程序中的Stripe访问webhook请求的原始正文。
在此示例之后,我将以下内容添加到具有需要原始主体的控制器方法的模块中。
function addRawBody(req, res, next) {
req.setEncoding('utf8');
let data = '';
req.on('data', (chunk) => {
data += chunk;
});
req.on('end', () => {
req.rawBody = data;
next();
});
}
export class SubscriptionModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(addRawBody)
.forRoutes('subscriptions/stripe');
}
}
Run Code Online (Sandbox Code Playgroud)
在控制器中,我正在使用@Req() req
然后req.rawBody
获取原始主体。我需要原始主体,因为Stripe api的constructEvent正在使用它来验证请求。
问题是请求被卡住了。似乎没有为数据或结束事件调用req.on。因此next()
在中间件中不被称为。
我也确实尝试过raw-body
像这里一样使用,但是得到的结果几乎相同。在这种情况下,req.read总是错误的,所以我也被困在那里。
我想这是Nest.js的问题,但我不确定...
Joe*_*aju 46
For anyone looking for a more elegant solution, turn off the bodyParser
in main.ts
. Create two middleware functions, one for rawbody
and the other for json-parsed-body
.
json-body.middleware.ts
import { Request, Response } from 'express';
import * as bodyParser from 'body-parser';
import { Injectable, NestMiddleware } from '@nestjs/common';
@Injectable()
export class JsonBodyMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: () => any) {
bodyParser.json()(req, res, next);
}
}
Run Code Online (Sandbox Code Playgroud)
raw-body.middleware.ts
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response } from 'express';
import * as bodyParser from 'body-parser';
@Injectable()
export class RawBodyMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: () => any) {
bodyParser.raw({type: '*/*'})(req, res, next);
}
}
Run Code Online (Sandbox Code Playgroud)
And apply the middleware functions to appropriate routes in app.module.ts
.
app.module.ts
[...]
export class AppModule implements NestModule {
public configure(consumer: MiddlewareConsumer): void {
consumer
.apply(RawBodyMiddleware)
.forRoutes({
path: '/stripe-webhooks',
method: RequestMethod.POST,
})
.apply(JsonBodyMiddleware)
.forRoutes('*');
}
}
[...]
Run Code Online (Sandbox Code Playgroud)
BTW req.rawbody
has been removed from express
long ago.
https://github.com/expressjs/express/issues/897
小智 11
今天,
因为我正在使用 NestJS 和 Stripe
我安装了 body-parser (npm),然后在 main.ts 中,添加
app.use('/payment/hooks', bodyParser.raw({type: 'application/json'}));
Run Code Online (Sandbox Code Playgroud)
并且将被限制在这条路线上!没有超载
cha*_*fir 10
2022 年第三季度更新
rawBody
现在可以通过专用选项 开箱即用:https: //docs.nestjs.com/faq/raw-body
ps 只是不要忘记将您的嵌套依赖项更新到最新版本:
npm update @nestjs/core
npm update @nestjs/common
npm update @nestjs/common
npm update @nestjs/platform-express //if you are using express
Run Code Online (Sandbox Code Playgroud)
昨晚我尝试验证Slack令牌时遇到了类似的问题。
我们使用的解决方案确实需要从核心Nest App禁用bodyParser,然后rawBody
在使用原始请求正文向请求中添加新密钥后重新启用它。
const app = await NestFactory.create(AppModule, {
bodyParser: false
});
const rawBodyBuffer = (req, res, buf, encoding) => {
if (buf && buf.length) {
req.rawBody = buf.toString(encoding || 'utf8');
}
};
app.use(bodyParser.urlencoded({verify: rawBodyBuffer, extended: true }));
app.use(bodyParser.json({ verify: rawBodyBuffer }));
Run Code Online (Sandbox Code Playgroud)
然后在我的中间件中,我可以像这样访问它:
const isVerified = (req) => {
const signature = req.headers['x-slack-signature'];
const timestamp = req.headers['x-slack-request-timestamp'];
const hmac = crypto.createHmac('sha256', 'somekey');
const [version, hash] = signature.split('=');
// Check if the timestamp is too old
// tslint:disable-next-line:no-bitwise
const fiveMinutesAgo = ~~(Date.now() / 1000) - (60 * 5);
if (timestamp < fiveMinutesAgo) { return false; }
hmac.update(`${version}:${timestamp}:${req.rawBody}`);
// check that the request signature matches expected value
return timingSafeCompare(hmac.digest('hex'), hash);
};
export async function slackTokenAuthentication(req, res, next) {
if (!isVerified(req)) {
next(new HttpException('Not Authorized Slack', HttpStatus.FORBIDDEN));
}
next();
}
Run Code Online (Sandbox Code Playgroud)
发光!
我用一行修好了它:)
main.ts
import * as express from 'express';
async function bootstrap() {
...
app.use('/your-stripe-webhook', express.raw({ type: "*/*" })); // <- add this!
...
await app.listen(8080)
}
Run Code Online (Sandbox Code Playgroud)
...不必添加任何中间件。...不必禁用 bodyParser
归档时间: |
|
查看次数: |
923 次 |
最近记录: |