Support

Find answers, guides, and tutorials to supercharge your content delivery.

Secure Token

Updated on July 6, 2021

Token authentication ensures that a request is only accessible with a valid token. There are two different ways to configure Secure Token:

  • Secure Token for Image Processing: Also known as signing requests. This configuration is about signing Image Processing requests. The main goal is authorizing valid request and blocking any unwanted image transformation. The expire parameter is not supported.
  • Secure Token for Access Control: This setup requires the token and expire parameter. It grants access for a defined time frame. Once a token has expired, it is not possible to access the content anymore. Several tokens with different expiration times can be created for the same file. A 403 Forbidden status will be returned if the token is not valid and a 410 Gone status if the token has expired.
Note: If using a Pull Zone for token authentication we recommend ensuring the Origin URL is not public and can't be easily guessed.

Secure Token for Image Processing

  1. Log in to the KeyCDN dashboard.
  2. In the left navigation sidebar click Zones.
  3. Click on the Zone menu that you want to add the token authentication and click Edit.
  4. Enable the Image Processing setting.
  5. Enable the Secure Token setting.
  6. Define a Secure Token Key. This key will be needed to generate the token.
  7. Use one of the code examples below to generate the token (e.g. from your website).

Format

If Image Processing is enabled, only the token parameter is supported.

https://zonename-hexid.kxcdn.com{path}?{querystring}&token={token}

Generate a token

If the overlay (watermark) parameter is used, it can be plain or encoded, but needs to be signed accordingly.

echo -n '{path}{querystring}{secret}' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =

Example:

echo -n '/path/to/example.jpgflip=1&width=400mysecret' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =

Secure Token for Access Control

  1. Log in to the KeyCDN dashboard.
  2. In the left navigation sidebar click Zones.
  3. Click on the Zone menu that you want to add the token authentication to and click Edit.
  4. Enable the Secure Token setting.
  5. Define a Secure Token Key. This key will be needed to generate the token.
  6. Optionally enable the Secure Token IP Address setting to add the client IP to the authentication token.
  7. Use one of the code examples below to generate the token (e.g. from your website).

Format

By default token authentication requires both the token and expire parameters.

https://zonename-hexid.kxcdn.com{path}?token={token}&expire={timestamp}

Generate a token

Path only

echo -n '{path}{secret}{timestamp}' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =

Example:

echo -n '/path/to/example.jpgmysecret1384719072' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =

Path and IP address

Having the IP address as part of Secure Token needs to be enabled in the KeyCDN dashboard. If an IP address is added, the content can only be accessed from this IP address with a valid token.

echo -n '{path}{IPaddress}{secret}{timestamp}' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =

Example:

echo -n '/path/to/example.jpg111.222.111.222mysecret1384719072' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =

Code examples

Below are different code examples for Access Control. The code might need to be adjusted based on the settings and setup.

PHP

<?php
    $secret = 'securetokenkey';
    $path = '/path/to/example.jpg';

    // Expiration in seconds (e.g. 90 seconds)
    $expire = time() + 90;

    // Generate token
    $md5 = md5($path.$secret.$expire, true);

    $md5 = base64_encode($md5);
    $md5 = strtr($md5, '+/', '-_');
    $md5 = str_replace('=', '', $md5);

    // Use this URL
    $url = "https://zonename-hexid.kxcdn.com{$path}?token={$md5}&expire={$expire}";

    echo $url;
?>

Python

import base64
from hashlib import md5
from time import time

secret = 'your_secret'
path = "/path/to/example.jpg"

# expiration in seconds (e.g. 180 seconds)
expire = int(time()) + 180

# generate token
token = base64.encodestring(
    md5(
        "%s%s%s" % (path, secret, expire)
    ).digest()
).replace("\n", "").replace("+", "-").replace("/", "_").replace("=", "")
secured_url = "https://zonename-hexid.kxcdn.com%s?token=%s&expire=%s" % (path, token, expire)

# return secured URL
print secured_url

Ruby

require 'digest/md5'
require 'base64'

secret = 'your_secret'
path = '/path/to/your/example.jpg'

# expiry time in seconds (e.g. 3600 seconds)
expire = Time.now.to_i + 3600
token = Base64.encode64(
    Digest::MD5.digest(
        "#{path}#{secret}#{expire}"
    )
).gsub("\n", "").gsub("+", "-").gsub("/", "_").gsub("=", "")

# final secured URL
url = "https://zonename-hexid.kxcdn.com#{path}?token=#{token}&expire=#{expire}"

puts url

Node.js

var crypto = require('crypto'),
    secret = 'your_secret',
    path = '/path/to/your/example.jpg';

// define expiry (e.g. 120 seconds)
var expire = Math.round(Date.now()/1000) + 120;

// generate md5 token
var md5String = crypto
    .createHash("md5")
    .update(path + secret + expire)
    .digest("binary");

// encode and format md5 token
var token = new Buffer(md5String, 'binary').toString('base64');
token = token.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');

// return secure token
console.log('https://zonename-hexid.kxcdn.com' + path + '?token=' + token + '&expire=' + expire);

Java

import java.util.Date;
import org.apache.commons.codec.binary.Base64;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.MessageDigest;

public class getSecureURL {

    // generate token
    private static String getBinaryToken(String path, String secret, Long expire) throws UnsupportedEncodingException, NoSuchAlgorithmException{

        String urlData = path + secret + expire.toString();
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] messageDigest = md.digest(urlData.getBytes());
        String token = Base64.encodeBase64URLSafeString(messageDigest);

        return token;

    }

    // main method
    public static void main(String[] args) throws Exception{

        String secret = "your_secret";
        String path = "/path/to/your/example.jpg";

        Date date = new Date();
        // expiry time (e.g. 300 seconds)
        Long expire = (date.getTime()/1000) + 300;
        String token = "" ;

        try {
            md5 = getBinaryToken(path, secret, expire);

            // final secured URL with token and expire variables
            String url = "https://zonename-hexid.kxcdn.com" + path + "?token=" + md5 + "&expire=" + expire.toString() ;
            System.out.println("genrated url : " + url);
        } catch (Exception e){
            e.printStackTrace();
        }

    }

}

Example:

https://zonename-hexid.kxcdn.com/path/to/example.jpg?token=85b9a81b78b24b4d18303c91b79e0124&expire=1384719072

Supercharge your content delivery 🚀

Try KeyCDN with a free 14 day trial, no credit card required.

Get started
KeyCDN uses cookies to make its website easier to use. Learn more