8
n8n 中文网amn8n.com

使用Bearer令牌认证和Airtable验证API请求

高级

这是一个Engineering领域的自动化工作流,包含 24 个节点。主要使用 If, Code, Webhook, Airtable, HttpRequest 等节点。 使用Bearer令牌认证和Airtable验证API请求

前置要求
  • HTTP Webhook 端点(n8n 会自动生成)
  • Airtable API Key
  • 可能需要目标 API 的认证凭证

分类

工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "2e491e733aabd347ba9dbe351de2eb0282b95dd5f327bc32034e70bc5642d897"
  },
  "nodes": [
    {
      "id": "a016798d-de6f-418d-9424-3787d9c9f7cc",
      "name": "Active",
      "type": "n8n-nodes-base.if",
      "position": [
        -1880,
        560
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "2e4151fc-f513-4a1d-8e42-c77857de22bc",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json['Is Active'] }}",
              "rightValue": "Active"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f71b6bbc-8bcf-4d43-9e3e-50b13c1f181e",
      "name": "invalid token",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -1880,
        760
      ],
      "parameters": {
        "options": {
          "responseCode": 400
        },
        "respondWith": "json",
        "responseBody": "{\n\"success\": false,\n\"error\": \"Invalid token\"\n}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "34a75954-111b-4975-b1c9-ed47ebc48753",
      "name": "expired",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -1660,
        660
      ],
      "parameters": {
        "options": {
          "responseCode": 401
        },
        "respondWith": "json",
        "responseBody": "{\n\"success\": false,\n\"error\": \"Token is expired\"\n}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "1edc90cc-ca3f-446c-9f8b-1c0818e35f85",
      "name": "Owner?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1220,
        360
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "901aa9e9-2952-44eb-97d1-4f9fcd7e0c74",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Get token').item.json['Issued To'][0] }}",
              "rightValue": "={{ $('Find job').item.json.Users[0] }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "843a59fe-3ace-4b90-9609-bccb165880a2",
      "name": "job not found",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -1220,
        560
      ],
      "parameters": {
        "options": {
          "responseCode": 404
        },
        "respondWith": "json",
        "responseBody": "{\n\"success\": false,\n\"error\": \"Job not found.\"\n}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "d94d02b7-e7fb-48b9-93fc-ec405c83ef17",
      "name": "unauthorized",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -1000,
        460
      ],
      "parameters": {
        "options": {
          "responseCode": 401
        },
        "respondWith": "json",
        "responseBody": "{\n\"success\": false,\n\"error\": \"Unauthorized. You don't have the permission to access this job.\"\n}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "df074a23-504f-468c-8ddf-0f09c86fdce1",
      "name": "Other methods",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -2980,
        1100
      ],
      "webhookId": "3a898a00-f298-4d47-b1d0-26d2eb6d1898",
      "parameters": {
        "path": "test-jobs",
        "options": {},
        "httpMethod": [
          "POST",
          "DELETE",
          "HEAD",
          "PATCH",
          "PUT"
        ],
        "responseMode": "responseNode",
        "multipleMethods": true
      },
      "typeVersion": 2
    },
    {
      "id": "6f2ffc33-2cfb-4230-bbae-205c3f79fa9b",
      "name": "GET jobs",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -2980,
        760
      ],
      "webhookId": "4ee81ec9-d972-410d-81f1-6c95de6266b5",
      "parameters": {
        "path": "test-jobs",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "a123e6ba-8f2a-4217-8917-531081296b74",
      "name": "405 Error",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -2760,
        1140
      ],
      "parameters": {
        "options": {
          "responseCode": 405
        },
        "respondWith": "json",
        "responseBody": "{\n  \"error\": \"Use GET request instead\"\n}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "715c08ef-401c-46a0-9551-674e06db66ed",
      "name": "Get token",
      "type": "n8n-nodes-base.airtable",
      "position": [
        -2320,
        660
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appbw5TEhn8xIxxXR",
          "cachedResultUrl": "https://airtable.com/appbw5TEhn8xIxxXR",
          "cachedResultName": "Testing Bearer Auth "
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblnqvjl4U2t9OMQD",
          "cachedResultUrl": "https://airtable.com/appbw5TEhn8xIxxXR/tblnqvjl4U2t9OMQD",
          "cachedResultName": "Tokens"
        },
        "options": {},
        "operation": "search",
        "filterByFormula": "={token id} = \"{{ $('GET jobs').first().json.headers.authorization.replace('Bearer ', '') }}\""
      },
      "credentials": {
        "airtableTokenApi": {
          "id": "SCfOTbIrHHSfAWgr",
          "name": "Testing Bearer Auth "
        }
      },
      "typeVersion": 2.1,
      "alwaysOutputData": true
    },
    {
      "id": "b7b3c90a-0bbd-4017-a84e-3e99468918ad",
      "name": "Validator",
      "type": "n8n-nodes-base.code",
      "position": [
        -2760,
        760
      ],
      "parameters": {
        "jsCode": "const input = $json;\n\nconst headers = input.headers || {};\nconst query = input.query || {};\n\nif (!headers.authorization) {\n  return [{ json: { success: false, reason: \"Missing Authorization header\" } }];\n}\n\nif (!headers.authorization.startsWith(\"Bearer \")) {\n  return [{ json: { success: false, reason: \"Authorization header must start with 'Bearer '\" } }];\n}\n\nif (!query.hasOwnProperty(\"job_id\")) {\n  return [{ json: { success: false, reason: \"Missing 'job_id' in query\" } }];\n}\n\nif (Object.keys(query).length !== 1) {\n  return [{ json: { success: false, reason: \"Query must contain only 'job_id'\" } }];\n}\n\nreturn [{ json: { success: true } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d8ebf36f-5715-43e6-8466-f939f15b6a70",
      "name": "Valid",
      "type": "n8n-nodes-base.if",
      "position": [
        -2540,
        760
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "9683899c-af40-414d-bb28-573261ac2c91",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.success }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "3db1de49-9aa2-4d73-96de-2fce13db437c",
      "name": "Unauthorized",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -2320,
        860
      ],
      "parameters": {
        "options": {
          "responseCode": 401
        },
        "respondWith": "json",
        "responseBody": "={\n  \"error\": \"{{ $json.reason }}\"\n}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "c6104dd7-4bdb-4d49-8ad4-2bc080731566",
      "name": "Find job",
      "type": "n8n-nodes-base.airtable",
      "position": [
        -1660,
        460
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appbw5TEhn8xIxxXR",
          "cachedResultUrl": "https://airtable.com/appbw5TEhn8xIxxXR",
          "cachedResultName": "Testing Bearer Auth "
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblS005mLwt03o4vV",
          "cachedResultUrl": "https://airtable.com/appbw5TEhn8xIxxXR/tblS005mLwt03o4vV",
          "cachedResultName": "Jobs"
        },
        "options": {},
        "operation": "search",
        "filterByFormula": "={job id} = \"{{ $('GET jobs').item.json.query.job_id }}\" "
      },
      "credentials": {
        "airtableTokenApi": {
          "id": "SCfOTbIrHHSfAWgr",
          "name": "Testing Bearer Auth "
        }
      },
      "typeVersion": 2.1,
      "alwaysOutputData": true
    },
    {
      "id": "e895c126-e103-43d0-ad72-d2c2c9d25dd9",
      "name": "format job",
      "type": "n8n-nodes-base.code",
      "position": [
        -1000,
        260
      ],
      "parameters": {
        "jsCode": "const record = $json;\n\nconst keyMapping = {\n    \"id\": \"id\",\n    \"createdTime\": \"created_time\",\n    \"Job Title\": \"job_title\",\n    \"Location\": \"location\",\n    \"Job Type\": \"job_type\",\n    \"Company Name\": \"company_name\",\n    \"Number of Applicants\": \"applicants\",\n    \"Salary Midpoint\": \"salary\"\n};\n\nlet jobObject = { success: true };\n\nfor (let key in keyMapping) {\n    if (record[key] !== undefined) {\n        jobObject[keyMapping[key]] = record[key];\n    }\n}\n\nreturn [{\n    json: {\n        job: [jobObject]\n    }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "f810df27-7b3f-4983-8f40-591be7f1fdd3",
      "name": "Return data",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -780,
        260
      ],
      "parameters": {
        "options": {
          "responseCode": 200
        },
        "respondWith": "json",
        "responseBody": "={{ $json.job }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "f21827e3-77fb-4889-aacd-dd26edec6978",
      "name": "When clicking ‘Execute workflow’",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -2960,
        380
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "59d6d0fb-89a2-4cf9-8c39-a1e2ed3e28bd",
      "name": "Make a request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2740,
        380
      ],
      "parameters": {
        "url": "https://localhost:8080/webhook/test-jobs",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "job_id",
              "value": "recfCIKgmo9gZUCjj"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer abc123"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "2b5c7b64-b223-4565-8b15-1359368d045b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3020,
        320
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 220,
        "content": "## Test the request"
      },
      "typeVersion": 1
    },
    {
      "id": "e106bd6e-2209-40bf-9a52-619b1d71ce3e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3020,
        1040
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 280,
        "content": "## HTTP Method handler"
      },
      "typeVersion": 1
    },
    {
      "id": "a3353e22-dca3-43e5-9914-d6cbdfc042b4",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2400,
        560
      ],
      "parameters": {
        "color": 6,
        "width": 260,
        "height": 260,
        "content": "## Database Example\nClone this [Airtable Base](https://airtable.com/appbw5TEhn8xIxxXR/shrN8ve4dfJIXjcAm)"
      },
      "typeVersion": 1
    },
    {
      "id": "a7999c83-fde9-42db-8ed1-8341f970dc9a",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3640,
        320
      ],
      "parameters": {
        "color": 4,
        "width": 580,
        "height": 1000,
        "content": "## Bearer Token Validation\n\n\nThis n8n template helps you manage and validate tokens easily using:\n\n- n8n as your backend workflow engine  \n- Airtable as your lightweight token store\n\n---\n\n### 🚀 What It Does\n\n- Stores user tokens securely in Airtable with expiry or usage metadata.\n- Validates incoming tokens in your workflows (e.g., webhook APIs).\n- Rejects invalid or expired tokens automatically for security.\n- Can be extended to generate, rotate, or revoke tokens for user management.\n\n---\n\n### How It Works\n\n1. **Webhook node** receives requests with a `Bearer` header.\n2. **Airtable Query** looks up the provided token.\n3. **Validation Logic (Code node)**:\n   - Checks if the token exists.\n   - Verifies expiry or usage limits if configured.\n4. Returns **success** if valid, or **error** if error with describing the issue.\n\n---\n\n- Note: This is the simplest way to do auth, just for simplification\n\n---\n\n### Why Use This\n\n- No need for a full backend to manage secure token validation.\n- Clean, modular, and ready for your SaaS workflows.\n\n---\n\nEnjoy building secure automations with **n8n + Airtable**! 🚀\n\n### Built by:\n[Nazmy](https://n8n.io/creators/islamnazmi/)"
      },
      "typeVersion": 1
    },
    {
      "id": "36023f3f-f1c2-42b0-a5c7-c378c8ade98b",
      "name": "Token Exists",
      "type": "n8n-nodes-base.if",
      "position": [
        -2100,
        660
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "6f16470a-aae4-4647-850e-332284b00a9f",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.id }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6d6ec65d-7228-4fd0-a152-071d8d4309f1",
      "name": "Job found?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1440,
        460
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "72d44236-9676-441d-99c7-0c48c5188447",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.id }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    }
  ],
  "pinData": {
    "GET jobs": [
      {
        "body": {},
        "query": {
          "job_id": "recfCIKgmo9gZUCjj"
        },
        "params": {},
        "headers": {
          "host": "api.hirempire.com",
          "accept": "application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7",
          "x-real-ip": "4.232.169.169",
          "user-agent": "axios/1.8.3",
          "authorization": "Bearer abc123",
          "accept-encoding": "gzip, compress, deflate, br",
          "x-forwarded-for": "4.232.169.169",
          "x-forwarded-host": "api.hirempire.com",
          "x-forwarded-port": "443",
          "x-forwarded-proto": "https",
          "x-forwarded-server": "e7eadafaf720"
        },
        "webhookUrl": "https://api.hirempire.com/v1/jobs",
        "executionMode": "production"
      }
    ]
  },
  "connections": {
    "Valid": {
      "main": [
        [
          {
            "node": "Get token",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Unauthorized",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Active": {
      "main": [
        [
          {
            "node": "Find job",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "expired",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Owner?": {
      "main": [
        [
          {
            "node": "format job",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "unauthorized",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find job": {
      "main": [
        [
          {
            "node": "Job found?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET jobs": {
      "main": [
        [
          {
            "node": "Validator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get token": {
      "main": [
        [
          {
            "node": "Token Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validator": {
      "main": [
        [
          {
            "node": "Valid",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Job found?": {
      "main": [
        [
          {
            "node": "Owner?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "job not found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "format job": {
      "main": [
        [
          {
            "node": "Return data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Token Exists": {
      "main": [
        [
          {
            "node": "Active",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "invalid token",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Other methods": {
      "main": [
        [
          {
            "node": "405 Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "405 Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "405 Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "405 Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "405 Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Execute workflow’": {
      "main": [
        [
          {
            "node": "Make a request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级 - 工程

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量24
分类1
节点类型8
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

外部链接
在 n8n.io 查看

分享此工作流