跳轉至

腳本開發 / API 認證

對於「函數 API」所生成的 HTTP API,可以額外添加接口認證。

目前支持的接口認證如下:

認證類型 説明
固定字段 驗證請求的 Header, Query 或 Body 中必須包含具有特定值的字段
HTTP Basic 標準 HTTP Basic 認證(在瀏覽器中訪問可彈出登錄框)
HTTP Digest 標準 HTTP Digest 認證(在瀏覽器中訪問可彈出登錄框)
認證函數 指定自行編寫的函數作為認證函數

用户可以在「管理 / API 認證」添加認證配置,隨後在「函數 API 配置」中指定所添加的認證配置。

如對安全性有較高要求,請務必使用 HTTPS 方式訪問接口

1. 固定字段認證

固定字段認證是最簡單的認證方式,即客户端與 DataFlux Func 約定在請求的某處(Header、Query 或 Body)包含一個特定的字段和字段值,在每次調用時附帶此內容以完成認證。

假設約定每次請求中,請求頭必須包含 x-auth-token="my-auth-token",那麼按照以下方式調用即可完成認證:

Text Only
1
2
GET /api/v1/al/func-api-xxxxx
x-auth-token: my-auth-token

配置多個固定字段認證時,有一個匹配即認為通過認證

對於 Query 和 Body 中用於認證的字段,認證通過後系統會自動將其刪除,不會傳遞到函數

2. HTTP Basic / HTTP Digest

瀏覽器直接支持的認證方式。

使用此方式認證的接口,在瀏覽器地址欄中直接訪問時,瀏覽器會彈出用户名/密碼框供用户填寫。

如需要使用編程方式訪問,請參考如下代碼:

Python
1
2
3
4
5
6
7
8
import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth

# HTTP Basic 認證
resp = requests.get(url_1, auth=HTTPBasicAuth('user', 'password'))

# HTTP Digest 認證
resp = requests.get(url_2, auth=HTTPDigestAuth('user', 'password'))

3. 認證函數

如果接口認證方式複雜或特殊(如需要對接業務系統等),可以選擇自行編寫函數方式認證。

用於認證的函數不需要參數,返回 True 表示認證成功,返回其他內容或拋出錯誤表示失敗。

在認證函數中,可以使用內置變量 _DFF_HTTP_REQUEST 獲取請求相關信息:腳本開發 / 內置變量 / _DFF_HTTP_REQUEST

示例
1
2
3
@DFF.API('認證函數')
def my_auth_func():
    return _DFF_HTTP_REQUEST['headers']['x-auth-token'] == 'my-auth-token'

需要注意的是,在認證失敗時,根據返回內容不同,接口的返回格式也會有所不同:

示例
1
2
3
@DFF.API('認證函數')
def my_auth_func():
    return False

認證失敗,直接返回 False 時,接口響應體中不會包含任何具體錯誤信息:

接口響應體
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  "ok"     : false,
  "error"  : 401.99,
  "reason" : "EAPIAuth",
  "message": "Func Auth failed",
  "detail" : false,
  "status" : 401,
  "reqDump": {
    "method": "GET",
    "url"   : "http://localdev:8089/api/v1/func-api/xxxxx/s"
  },
  "traceId"   : "TRACE-XXXXX",
  "clientTime": null,
  "reqTime"   : "2025-08-14T11:03:45.238Z",
  "respTime"  : "2025-08-14T11:03:45.406Z",
  "reqCost"   : 168
}
示例
1
2
3
@DFF.API('認證函數')
def my_auth_func():
    return 'Bad User!'

認證失敗,返回字符串時,此字符串會作為 detail 字段返回:

接口響應體
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  "ok"     : false,
  "error"  : 401.99,
  "reason" : "EAPIAuth",
  "message": "Func Auth failed",
  "detail" : "Bad User!",
  "status" : 401,
  "reqDump": {
    "method": "GET",
    "url"   : "http://localdev:8089/api/v1/func-api/xxxxx/s"
  },
  "traceId"   : "TRACE-XXXXX",
  "clientTime": null,
  "reqTime"   : "2025-08-14T11:03:45.238Z",
  "respTime"  : "2025-08-14T11:03:45.406Z",
  "reqCost"   : 168
}
示例
1
2
3
@DFF.API('認證函數')
def my_auth_func():
    return { 'error': 'Bad User!' }

認證失敗,返回 JSON 時,此 JSON 會作為 detail 字段返回:

接口響應體
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
  "ok"     : false,
  "error"  : 401.99,
  "reason" : "EAPIAuth",
  "message": "Func Auth failed",
  "detail": {
    "error": "Bad User!"
  },
  "status": 401,
  "reqDump": {
    "method": "GET",
    "url"   : "http://localdev:8089/api/v1/func-api/xxxxx/s"
  },
  "traceId"   : "TRACE-XXXXX",
  "clientTime": null,
  "reqTime"   : "2025-08-14T11:03:45.238Z",
  "respTime"  : "2025-08-14T11:03:45.406Z",
  "reqCost"   : 168
}
示例
1
2
3
@DFF.API('認證函數')
def my_auth_func():
    raise Exception('Bad User!')

當認證函數拋出錯誤時,由於 Func 框架層面無法感知此 Exception 屬於業務邏輯還是代碼本身報錯,因此會返回通用的錯誤信息作為 detail 字段:

接口響應體
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
  "ok": false,
  "error": 401.99,
  "reason": "EAPIAuth",
  "message": "Func Auth failed",
  "detail": {
    "name"               : "Func.Runner",
    "id"                 : "task-RWLH3EuCRfYl",
    "triggerTime"        : 1755170213.119,
    "startTime"          : 1755170213.122,
    "endTime"            : 1755170213.13,
    "status"             : "failure",
    "exceptionType"      : "UserScriptException",
    "exception"          : "In User Script: Exception('Bad User!')",
    "exceptionFrom"      : "userScript",
    "originExceptionType": "Exception",
    "originException"    : "Exception('Bad User!')"
  },
  "status": 401,
  "reqDump": {
    "method": "GET",
    "url"   : "http://localdev:8089/api/v1/func-api/xxxxx/s"
  },
  "traceId"   : "TRACE-XXXXX",
  "clientTime": null,
  "reqTime"   : "2025-08-14T11:03:45.238Z",
  "respTime"  : "2025-08-14T11:03:45.406Z",
  "reqCost"   : 168
}