You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AWS EB部署的Node.js服务器验证Hasura事件与动作请求来源

验证Hasura请求到Node.js端点的方法

要确保你的Node.js端点只接收来自Hasura的请求,主要有两种可靠的实现方式,下面分别给出具体方案和authCheckThisCameFromMyHasura方法的代码:

方案1:使用预共享API密钥(简单易实现)

这种方式适合快速搭建验证逻辑,核心是在Hasura的请求中添加自定义头部,Node.js端校验头部值是否匹配预设的密钥。

步骤:

  1. 在Hasura中配置请求头

    • 无论是事件触发器还是自定义动作,在Hasura的配置里添加一个自定义请求头(比如X-Hasura-Secret),值设为一个强随机字符串(比如32位UUID)。
  2. 在AWS EB中设置环境变量

    • 登录AWS Elastic Beanstalk控制台,找到你的应用环境,进入「配置」->「软件」,在「环境属性」里添加HASURA_SECRET,值设为和Hasura中一致的密钥。
  3. 实现验证方法

    const express = require('express');
    const app = express();
    
    // 解析JSON格式的请求体
    app.use(express.json());
    
    // 验证请求是否来自Hasura的方法
    function authCheckThisCameFromMyHasura(req) {
        // 从请求头获取传入的密钥
        const incomingSecret = req.headers['x-hasura-secret'];
        // 从环境变量读取预设的合法密钥
        const validSecret = process.env.HASURA_SECRET;
    
        // 校验:密钥存在且完全匹配
        return incomingSecret && validSecret && incomingSecret === validSecret;
    }
    
    app.post('/some-event-or-action', (req, res) => {
        if(authCheckThisCameFromMyHasura(req)){
            // 执行你的业务逻辑
            res.status(200).json({ success: true });
        } else {
            // 验证失败,返回403无权访问
            res.status(403).json({ error: 'Unauthorized' });
        }
    });
    
    app.listen(process.env.PORT || 3000, () => {
        console.log('Server running');
    });
    

方案2:使用Hasura请求签名(更安全)

Hasura支持用HMAC签名请求,签名基于请求体和密钥生成,密钥不会在请求中传输,能有效防止密钥泄露风险,安全性更高。

步骤:

  1. 在Hasura中配置签名密钥

    • 在Hasura控制台的「Settings」->「API」->「Webhook/Action Signature」里,设置一个强随机字符串作为签名密钥,并启用签名功能。
  2. 在AWS EB中设置环境变量

    • 添加HASURA_SIGNATURE_SECRET环境变量,值设为Hasura中配置的签名密钥。
  3. 实现验证方法

    const express = require('express');
    const crypto = require('crypto');
    const app = express();
    
    // 先获取原始请求体Buffer,不能提前解析JSON(签名基于原始内容生成)
    app.use(express.raw({ type: 'application/json' }));
    
    function authCheckThisCameFromMyHasura(req) {
        const signatureHeader = req.headers['x-hasura-signature'];
        const secret = process.env.HASURA_SIGNATURE_SECRET;
    
        if (!signatureHeader || !secret) {
            return false;
        }
    
        // Hasura签名格式为sha256=<哈希值>,拆分出哈希部分
        const [algorithm, incomingHash] = signatureHeader.split('=');
        if (algorithm !== 'sha256') {
            return false;
        }
    
        // 用密钥和原始请求体生成HMAC哈希
        const hmac = crypto.createHmac('sha256', secret);
        const computedHash = hmac.update(req.body).digest('hex');
    
        // 用timingSafeEqual防止时序攻击,比较哈希值是否一致
        return crypto.timingSafeEqual(Buffer.from(incomingHash), Buffer.from(computedHash));
    }
    
    app.post('/some-event-or-action', (req, res) => {
        if(authCheckThisCameFromMyHasura(req)){
            // 手动将原始请求体解析为JSON
            const body = JSON.parse(req.body);
            // 执行业务逻辑
            res.status(200).json({ success: true });
        } else {
            res.status(403).json({ error: 'Unauthorized' });
        }
    });
    
    app.listen(process.env.PORT || 3000, () => {
        console.log('Server running');
    });
    

补充说明

  • 环境变量也可以通过EB的.ebextensions配置文件批量设置,比如创建config/01-environment-variables.config:
    option_settings:
      - namespace: aws:elasticbeanstalk:application:environment
        option_name: HASURA_SECRET
        value: your-secret-here
      - namespace: aws:elasticbeanstalk:application:environment
        option_name: HASURA_SIGNATURE_SECRET
        value: your-signature-secret-here
    
  • 若使用Hasura Cloud,可结合IP白名单进一步限制请求来源,但需注意Hasura Cloud的出口IP可能变动,需要定期更新白名单。

内容的提问来源于stack exchange,提问作者AndyW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 13:57:41