title: dingtalk-auth keywords:

  • Apache APISIX
  • API Gateway
  • Plugin
  • DingTalk Auth
  • dingtalk-auth description: This document contains information about the Apache APISIX dingtalk-auth Plugin.

Description

The dingtalk-auth Plugin integrates DingTalk OAuth 2.0 authentication into APISIX routes. It validates a DingTalk authorization code, exchanges it for an access token, and retrieves user information from the DingTalk open platform. Verified user information is cached in a secure cookie session so that subsequent requests are not interrupted.

Attributes

NameTypeRequiredDefaultDescription
app_keystringTrueDingTalk application App Key (client ID).
app_secretstringTrueDingTalk application App Secret (client secret). This field is stored encrypted.
secretstringTrueKey used to sign and encrypt the cookie session (8–32 characters). This field is stored encrypted.
redirect_uristringTrueURI to redirect the user to when no valid authorization code or session is present.
code_headerstringFalseX-DingTalk-CodeHTTP request header name from which to read the DingTalk authorization code.
code_querystringFalsecodeQuery parameter name from which to read the DingTalk authorization code.
access_token_urlstringFalsehttps://api.dingtalk.com/v1.0/oauth2/accessTokenDingTalk endpoint used to obtain an access token.
userinfo_urlstringFalsehttps://oapi.dingtalk.com/topapi/v2/user/getuserinfoDingTalk endpoint used to retrieve user information.
set_userinfo_headerbooleanFalsetrueWhen true, the verified user information is Base64-encoded and forwarded to the upstream in the X-Userinfo header.
timeoutintegerFalse6000Timeout in milliseconds for HTTP calls to DingTalk APIs.
ssl_verifybooleanFalsetrueWhether to verify the SSL certificate when calling DingTalk APIs.
cookie_expires_inintegerFalse86400Cookie session validity period in seconds.
secret_fallbacksarrayFalseList of fallback secrets used during key rotation (each 8–32 characters).

:::note

encrypt_fields = {"app_secret", "secret"} is defined in the schema, which means both fields are stored encrypted in etcd. See encrypted storage fields.

:::

Authentication flow

Client                     APISIX (dingtalk-auth)            DingTalk
  │                               │                               │
  │──── GET /resource ───────────►│                               │
  │                               │  (no session, no code)        │
  │◄─── 302 → redirect_uri ───────│                               │
  │                               │                               │
  │──── GET /resource?code=xxx ──►│                               │
  │                               │──── POST /accessToken ───────►│
  │                               │◄─── {"accessToken": "..."} ───│
  │                               │──── POST /getuserinfo ────────►│
  │                               │◄─── {"result": {...}} ─────────│
  │                               │  (save userinfo in session)   │
  │◄─── 200 + Set-Cookie ─────────│                               │
  │                               │                               │
  │──── GET /resource (Cookie) ──►│                               │
  │                               │  (session valid, skip auth)   │
  │◄─── 200 ──────────────────────│                               │

Enable Plugin

You can enable the Plugin on a specific Route as shown below:

:::note You can fetch the admin_key from config.yaml and save to an environment variable with the following command:

admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

:::

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
  -H "X-API-KEY: $admin_key" \
  -X PUT \
  -d '{
    "methods": ["GET"],
    "uri": "/anything/*",
    "plugins": {
      "dingtalk-auth": {
        "app_key": "<your-app-key>",
        "app_secret": "<your-app-secret>",
        "secret": "<session-secret-key>",
        "redirect_uri": "https://login.dingtalk.com/oauth2/auth?..."
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

Example usage

Once you have enabled the Plugin, incoming requests to the Route are processed as follows:

  1. No session and no code: The user is redirected to redirect_uri (typically a DingTalk OAuth login page) with a 302 response.
  2. Authorization code present (in the code query parameter or X-DingTalk-Code header): The Plugin exchanges the code for an access token via access_token_url, then retrieves user information from userinfo_url. On success, the user information is stored in an encrypted cookie session and the original request proceeds.
  3. Valid session cookie: Subsequent requests carrying the session cookie bypass DingTalk API calls entirely and proceed directly to the upstream.

When set_userinfo_header is true (the default), the upstream receives the DingTalk user information in the X-Userinfo header as a Base64-encoded JSON object.

Custom code extraction

By default the Plugin reads the authorization code from the code query parameter or the X-DingTalk-Code header. You can customize both names:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
  -H "X-API-KEY: $admin_key" \
  -X PUT \
  -d '{
    "methods": ["GET"],
    "uri": "/anything/*",
    "plugins": {
      "dingtalk-auth": {
        "app_key": "<your-app-key>",
        "app_secret": "<your-app-secret>",
        "secret": "<session-secret-key>",
        "redirect_uri": "https://login.dingtalk.com/oauth2/auth?...",
        "code_query": "dt_code",
        "code_header": "X-Custom-DT-Code"
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

Key rotation

Use secret_fallbacks to rotate the session signing key without invalidating existing sessions:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
  -H "X-API-KEY: $admin_key" \
  -X PUT \
  -d '{
    "methods": ["GET"],
    "uri": "/anything/*",
    "plugins": {
      "dingtalk-auth": {
        "app_key": "<your-app-key>",
        "app_secret": "<your-app-secret>",
        "secret": "<new-secret-key>",
        "secret_fallbacks": ["<old-secret-key>"],
        "redirect_uri": "https://login.dingtalk.com/oauth2/auth?..."
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

Delete Plugin

To remove the dingtalk-auth Plugin, delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect.

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
  -H "X-API-KEY: $admin_key" \
  -X PUT \
  -d '{
    "methods": ["GET"],
    "uri": "/anything/*",
    "plugins": {},
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'