跳转至

脚本开发 / 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
}