Configure URL signing

更新时间:
复制 MD 格式

Implement URL signing for Edge Security Accelerator (ESA) using Edge Function templates. Three methods (A, B, and C) use MD5-based signatures to protect resources such as files and API endpoints. Each method includes code examples and parameter descriptions.

How it works

URL signing protects your origin resources by blocking requests that fail authentication.

Authentication methods

ESA provides three authentication methods (A, B, and C). Each compares an MD5 hash in the URL against one computed at the point of presence (POP). Matching hashes allow the request; mismatches deny it.

Method A

  • Signed URL format: http://DomainName/Filename?auth_key={timestamp}-{rand}-{uid}-{md5hash}. Each field is defined in Parameters.

  • Example code

    import { createHash } from "node:crypto";
    
    async function handleRequest(request) {
      const url = new URL(request.url);
      const path = url.pathname;
      const delta = 3600;
    
      const authKeyTypeA = url.searchParams.get('auth_key');
    
      const privateKey = 'your_secret_key'
      const currentTimestamp = Math.floor(Date.now() / 1000);
    
      if (!authKeyTypeA) {
        return new Response('Unauthorized', { status: 401 });
      }
    
      const [timestamp, rand, uid, signature] = authKeyTypeA.split('-');
    
      if (currentTimestamp > parseInt(timestamp)+ delta) {
        return new Response('Link expired', { status: 403 });
      }
    
      const signString = [path, timestamp, rand, uid, privateKey].join('-');
    
      const md5 = createHash('md5').update(signString).digest('hex');
    
      if (md5 !== signature) {
        return new Response('Unauthorized', { status: 401 });
      }
    
      // If the resource is on another domain, fetch it and return the response
      // const yourUrl = `https://your-dcdn-domain.com${path}${url.search}`
      // const cdnResponse = await fetch(yourUrl, request)
      // return new Response(cdnResponse.body, cdnResponse)
    
      // In most cases, one origin fetch is sufficient
      return fetch(request.url)
    }
    
    export default {
      async fetch(request) {
        return handleRequest(request)
      }
    }

  • Test and verify

    • Test a valid signed URL: curl -I http://esa.aliyun.top/video/test.mp4?auth_key=1743388566-61b20a42d14f403ba3790d1b82502027-1-ee1c2c463a41ef4d72fcff5987f1e08c. A 200 response confirms successful authentication.

      image

    • Test an unsigned URL: curl -I http://esa.aliyun.top/test.mp4. A 401 response confirms the request was denied.

      image

Method B

  • Signed URL format: http://DomainName/{timestamp}/{md5hash}/FileName. Each field is defined in Parameters.

  • Example code

    import { createHash } from "node:crypto";
    
    function handleRequest(request) {
      const url = new URL(request.url);
      const path = url.pathname;
      const parts = path.split('/');
      const delta = 3600;
      const privateKey = 'your_secret_key'
      const currentTimestamp = Math.floor(Date.now() / 1000);
      const timestamp = parts[1];
      const signature = parts[2];
    
      if (!timestamp || !signature) {
        return new Response('Unauthorized', { status: 401 });
      }
    
      const filePath = '/' + parts.slice(3).join('/');
      const signString = [privateKey, timestamp, filePath].join('');
      const md5 = createHash('md5').update(signString).digest('hex');
    
      if (md5 !== signature) {
        return new Response('Unauthorized', { status: 401 });
      }
    
      if (currentTimestamp > parseInt(timestamp)+ delta) {
        return new Response('Link expired', { status: 403 });
      }
    
      // If the resource is on another domain, fetch it and return the response
      // const yourUrl = `https://your-dcdn-domain.com${path}${url.search}`
      // const cdnResponse = await fetch(yourUrl, request)
      // return new Response(cdnResponse.body, cdnResponse)
    
      // For Authentication Method B, reconstruct the original file path for the origin fetch.
      return fetch(url.origin + filePath)
    }
    
    export default {
      async fetch(request) {
        return handleRequest(request)
      }
    }

  • Test and verify

    • Test a valid signed URL: curl -I http://esa.aliyun.top/1743391454/f1415e282ae5ae650455e7b525231eff/test.mp4. A `200` response confirms successful authentication.

      image

    • Test an unsigned URL: http://esa.aliyun.top/test.mp4. A `401` response confirms the request was denied.

      image

Method C

  • Signed URL format: http://DomainName/{md5hash}/{timestamp}/FileName. Each field is defined in Parameters.

  • Example code

    import { createHash } from "node:crypto";
    
    function handleRequest(request) {
      const url = new URL(request.url);
      const path = url.pathname;
      const parts = path.split('/');
      const delta = 3600;
      const privateKey = 'your_secret_key'
      const currentTimestamp = Math.floor(Date.now() / 1000);
      const signature = parts[1];
      const hexTime = parts[2];
      const timestamp = parseInt(hexTime, 16);
    
      if (!hexTime || !signature) {
        return new Response('Unauthorized', { status: 401 });
      }
    
      const filePath = '/' + parts.slice(3).join('/');
      const signString = [privateKey, filePath, hexTime].join('-');
      const md5 = createHash('md5').update(signString).digest('hex');
    
      if (md5 !== signature) {
        return new Response('Unauthorized', { status: 401 });
      }
    
      if (currentTimestamp > parseInt(timestamp)+ delta) {
        return new Response('Link expired', { status: 403 });
      }
    
      // If the resource is on another domain, fetch it and return the response
      // const yourUrl = `https://your-dcdn-domain.com${path}${url.search}`
      // const cdnResponse = await fetch(yourUrl, request)
      // return new Response(cdnResponse.body, cdnResponse)
    
      // For Authentication Method C, reconstruct the original file path for the origin fetch.
      return fetch(url.origin + filePath)
    }
    
    export default {
      async fetch(request) {
        return handleRequest(request)
      }
    }

  • Test and verify

    • Test a valid signed URL: curl -I http://esa.aliyun.top/e59c904c85f19a48413b6283fc9d2f5a/1743400480/test.mp4. A `200` response confirms successful authentication.

      image

    • Test an unsigned URL: http://esa.aliyun.top/test.mp4. A `401` response confirms the request was denied.

      image

Parameters

  • DomainName: The DNS record for your ESA site.

  • timestamp: Unix timestamp (seconds since epoch) of when the signed URL was generated. Together with the TTL, this determines expiration. In Method C, the value is a hexadecimal string.

    Note

    A signed URL expires at timestamp plus a validity period configured in ESA. The example code sets this period in the `delta` variable.

  • FileName: Path to the requested file on the origin server. Must start with a forward slash (/).

  • md5hash: A 32-character hexadecimal string (0-9, a-z) generated by the MD5 algorithm.

    The md5hash is calculated as follows:

    • Authentication Method A: getMd5(FileName + "-" + timestamp + "-" + rand + "-" + uid + "-" + your_secret_key).

    • Authentication Method B: getMd5(your_secret_key + timestamp + FileName).

    • Authentication Method C: getMd5(your_secret_key + "-" + FileName + "-" + timestamp).

    Note

    You must implement the getMd5 function manually.

  • rand: A random string that makes each signed URL unique. Use a UUID without hyphens, such as 477b3bbc253f467b8def6711128c7bec.

  • uid: User ID. Set based on your business requirements.

  • auth_key: Authentication string composed of timestamp, rand, uid, and md5hash.