Node.js 中的 Webhooks 服务器
本文介绍了一个简单的 webhooks 服务器 示例。
我们强烈建议您不要在生产环境中使用它。
# 依赖项
这两个示例都使用 Express 库来创建 HTTP 端点。
此外,出于本地开发目的,需要隧道服务。此示例使用 ngrok。
npm install express jsonwebtoken
您可以在此处下载 ngrok:https://ngrok.com/download。
# 示例
下面是两个基于 Express 构建的 webhooks 服务器示例。
# 不检查请求签名的示例
这是一个非常简单的示例,服务器将来自请求的 body
记录到控制台。body
包含从 CKEditor 云服务发送的完整的 webhook 信息。
const express = require( 'express' );
const app = express();
app.use( express.json() );
app.post( '/', ( req, res ) => {
console.log( 'received webhook', req.body );
res.sendStatus( 200 );
} );
app.listen( 9000, () => console.log( 'Node.js server started on port 9000.' ) );
# 检查请求签名的示例
此示例更复杂,因为服务器除了将 webhook 信息记录到控制台外,还检查请求是否来自 CKEditor 云服务服务器,以及是否使用正确的 API 密钥 签名。
生成和检查签名需要几个变量。 API 密钥 可在 CKEditor 生态系统客户仪表板(针对 SaaS)或管理面板(针对本地部署)中找到,其余参数在请求中
method
:req.method
url
:req.url
timestamp
:req.headers[ 'x-cs-timestamp' ]
body
:req.rawBody
请注意,rawBody
字段是通过以下配置添加的
app.use( express.json( { verify: ( req, res, buffer ) => { req.rawBody = buffer; } } ) );
此字段在 Express 中默认不可用。Express 中可用的 body
字段包含已处理的数据,这些数据无法用于生成签名。
const crypto = require( 'crypto' );
const express = require( 'express' );
const app = express();
const API_SECRET = 'secret';
app.use( express.json( { verify: ( req, res, buffer ) => { req.rawBody = buffer; } } ) );
app.post( '/', ( req, res ) => {
const signature = _generateSignature( req.method, req.url, req.headers[ 'x-cs-timestamp' ], req.rawBody );
if ( signature !== req.headers[ 'x-cs-signature' ] ) {
return res.sendStatus( 401 );
}
console.log( 'received webhook', req.body );
res.sendStatus( 200 );
} );
app.listen( 9000, () => console.log( 'Node.js server started on port 9000.' ) );
function _generateSignature( method, url, timestamp, body ) {
const hmac = crypto.createHmac( 'SHA256', API_SECRET );
hmac.update( `${ method.toUpperCase() }${ url }${ timestamp }` );
if ( body ) {
hmac.update( body );
}
return hmac.digest( 'hex' );
}
# 用法
使用以下命令启动服务器
node index.js
如果服务器在端口 9000
上运行,请使用以下命令运行 ngrok
./ngrok http 9000
之后,您应该会看到一个 *.ngrok.io
URL。复制 *.ngrok.io
URL 并将其粘贴到 webhook 配置中。现在您应该能够接收 webhook。