Authentication

The API supports different authentication methods. For security reasons, some of the authentication methods are disabled by default. They can be enabled per access key in the API control panel.

  • HMAC based
  • HTTP Basic authentication (disabled by default)
  • User/Password in URL (disabled by default)

Note

Note: We recommend to use the HMAC based authentication method whenever possible as this method is inherently more secure than the other methods.

HMAC Based Authentication

Recognized parameters. 

NameDescriptionRequired
accesskey

The access key for the request sender. This parameter identifies the account that will be charged for the request. Access keys can be created in the API control panel. Additionally, the API control panel allows to set certain preferences and restrictions per access key.

Type: String

Example: NYczonwTxv

Yes
expires

The date and time at which the signature for this request will expire. After this time, the request will be declined. This time stamp cannot be more than 24 hours ahead from the time the request is submitted.

Type: Date/Time in ISO 8601 format (see [ISO8601])

Example: 2011-04-15T15:43:46Z

Condition: Either the time stamp or the expires parameter have to be supplied.

Conditional
timestamp

The date and time at which the request has been signed. If this timestamp does not match server time (with a grace period of +/- 15 minutes), the request will be declined.

Type: Date/Time in ISO 8601 format

Example: 2011-04-14T15:43:46Z

Condition: Either the timestamp or the expires parameter have to be supplied.

Conditional
signature

The signature for the request. The signature is created by applying the HMAC-SHA1 (RFC 2104) function to a concatenation of the called service name, signature timestamp or expiry timestamp and the secret key associated with the access key. The resulting data has to be encoded with the Base64 method.

Type: String

Example: 4KvntdTApUC2MO6FJQqwYeVxQX0=

Yes

Creating a Signature

Decide if you want to sign a single request by using the current timestamp, or you want to pre-sign several requests. Get the current system time and create either the timestamp or the expires parameter. The time in the timestamp can be either UTC (indicated by appending the character Z to the timestamp), or in local time (in this case, the difference to UTC has to be indicated by appending +HH:MM to the timestamp).

  1. Concatenate your access key, the service name and either the request timestamp or the expiry timestamp together. Do not use any characters to separate them.

  2. Use the newly created string and your secret key to create an RFC 2104 compliant signature. Use the SHA-1 hash algorithm for the calculation.

    A detailed description of the HMAC calculation can be found in [RFC2104].

  3. Apply the Base64 encoding (defined e.g. in [RFC4648]) to the calculated binary signature.

Example Signature and Request. Assuming the following values, an example signature and the resulting request URL will be shown:

Access key:
NYczonwTxv
Secret key:
x4whvXnG7cCOBiNBoi1r
Request timestamp:
2011-04-15T15:43:46Z
Service name:
timeservice
  1. Concatenate access key, service name and request timestamp: NYczonwTxvtimeservice2011-04-15T15:43:46Z.
  2. Calculate the HMAC by using the SHA-1 hash algorithm.
  3. Apply Base64 encoding to the resulting string: OlTRdhobJdUPDyM89lu0xKe4REY=.
  4. Construct the request. Remember to apply URL encoding to the parameter values in case your toolkit does not perform this operation automatically for your: http://api.xmltime.com/timeservice?accesskey=NYczonwTxv&timestamp=2011-04-15T15%3A43%3A46Z&signature=OlTRdhobJdUPDyM89lu0xKe4REY%3D&further parameters….

Sample Implementations. Many popular programming languages and scripting toolkits offer support for HMAC signing out of the box, or make it very easy to add support for it.

C#/.NET:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Security.Cryptography;
using System.Net;
using System.Web;
 
// ...
String entrypoint = "http://api.xmltime.com/";
String accesskey = "NYczonwTxv";
String secretkey = "x4whvXnG7cCOBiNBoi1r";

public String servicecall(String service, NameValueCollection iargs) {
    String timestamp, message;
    HMACSHA1 hmac;
    byte[] hash;
    NameValueCollection args;

    // Hash computation
    timestamp = DateTime.UtcNow.ToString("o");
    message = accesskey + service + timestamp;
    hmac = new HMACSHA1(System.Text.Encoding.ASCII.GetBytes(secretkey));
    hash = hmac.ComputeHash(System.Text.Encoding.ASCII.GetBytes(message));

    // Copy arguments and add authentication parameters
    args = new NameValueCollection(iargs);
    args.Set("accesskey", accesskey);
    args.Set("timestamp", timestamp);
    args.Set("signature", Convert.ToBase64String(hash));

    // Generate URI from the arguments
    List<String> items = new List<String>();
    foreach (String key in args.AllKeys)
        items.Add(String.Concat(HttpUtility.UrlEncode(key), "=", HttpUtility.UrlEncode(args[key])));

    UriBuilder uri = new UriBuilder(entrypoint + service);
    uri.Query = String.Join("&", items.ToArray());

    // Retrieve data and return it
    using (WebClient client = new WebClient()) {
        client.Encoding = System.Text.Encoding.UTF8;
        return client.DownloadString(uri.Uri);
    }
}

// Getting data as String:
String timedata = servicecall("timeservice",
        new NameValueCollection {{"placeid", "norway/oslo"}, {"out", "js"}})
Perl:
use Digest::HMAC_SHA1;
use LWP::Simple;
use URI::Escape;
use POSIX qw(strftime);

sub servicecall($%);

my ($entrypoint, $accesskey, $secretkey) =
    qw(http://api.xmltime.com/ NYczonwTxv x4whvXnG7cCOBiNBoi1r);

my $timedata = servicecall('timeservice', (placeid=>'norway/oslo', out=>'js');


sub servicecall($%) {
    my ($service, %args) = @_;
    my ($timestamp, $hmac, $signature, $query);

    $timestamp = strftime("%FT%T", gmtime());
    $hmac = Digest::HMAC_SHA1->new($secretkey);
    $hmac->add("$accesskey$service$timestamp");
    $signature = $hmac->b64digest;

    $args{accesskey} = $accesskey;
    $args{timestamp} = $timestamp;
    $args{signature} = $signature;

    $query = join(';', map { "$_=".uri_escape($args{$_}) } keys %args);

    return get("$entrypoint/$service?$query");
}
PHP:
The function hash_hmac() is available since version 5.1.2 of PHP.
$entrypoint = 'http://api.xmltime.com/';
$accesskey = 'NYczonwTxv';
$secretkey = 'x4whvXnG7cCOBiNBoi1r';

$timedata = servicecall('timeservice', array('placeid'=>'norway/oslo'));

function servicecall($service, $args) {
    global $entrypoint, $accesskey, $secretkey;

    $timestamp = gmdate('c');
    $message = "$accesskey$service$timestamp";
    $signature = base64_encode(hash_hmac('sha1', $message, $secretkey, true));

    $args['accesskey'] = $accesskey;
    $args['timestamp'] = $timestamp;
    $args['signature'] = $signature;

    $url = "$entrypoint/$service?" . http_build_query($args);

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}
Phyton:
import base64, datetime, hashlib, hmac, urllib

entrypoint = "http://api.xmltime.com/"
accesskey = "NYczonwTxv"
secretkey = "x4whvXnG7cCOBiNBoi1r"

def servicecall(service, args):
    global entrypoint, accesskey, secretkey

    timestamp = datetime.datetime.utcnow().isoformat()
    message = accesskey + service + timestamp
    digester = hmac.new(secretkey, message, hashlib.sha1)

    args['accesskey'] = accesskey
    args['timestamp'] = timestamp
    args['signature'] = base64.b64encode(digester.digest())

    url = entrypoint + '/' + service + '?' + urllib.urlencode(args)
    return urllib.urlopen(url).read()

timedata = servicecall("timeservice", dict(placeid=187, out='js'))
Ruby:
require 'base64'
require 'cgi'
require 'hmac-sha1'
require 'net/http'

$entrypoint = 'http://api.xmltime.com/'
$accesskey = 'NYczonwTxv'
$secretkey = 'x4whvXnG7cCOBiNBoi1r'

def servicecall(service, args)
    timestamp = Time.now.getutc.strftime('%FT%T')
    message = $accesskey + service + timestamp
    digest = HMAC::SHA1.digest($secretkey, message)

    args['accesskey'] = $accesskey
    args['timestamp'] = timestamp
    args['signature'] = Base64.encode64(digest).chomp

    query = args.collect do |key, value|
        [key.to_s, CGI::escape(value.to_s)].join('=')
    end.join(';')

    url = $entrypoint + '/' + service + '?' + query
    Net::HTTP.get(URI.parse(url))
end

timedata = servicecall('timeservice', { 'placeid'=>187, 'out'=>'js' })

HTTP Basic Authentication

The services also supports the Basic authentication scheme as defined in section 11.1 of [RFC1945]. Please be aware that this authentication method does not provide sufficient measures to protect your credentials. For this reason, you have to specifically enable it per access key on the preferences pages.

To use this authentication method, pass your access key as user name and the secret key as password to your toolkit.

Example Shell Commands. Assuming the following values, example requests with curl and wget are shown:

Access key:
NYczonwTxv
Secret key:
x4whvXnG7cCOBiNBoi1r
Service name:
timeservice
$ curl --user NYczonwTxv:x4whvXnG7cCOBiNBoi1r http://api.xmltime.com/timeservice?further parameters&hellip;
$ wget --user=NYczonwTxv --password=x4whvXnG7cCOBiNBoi1r http://api.xmltime.com/timeservice?further parameters&hellip;

Note

The shown method of supplying the password to curl and wget might reveal your password to other users working on the same machine or show it in your shell history. Both curl and wget are also able to read the password from a file, which would avoid this problem. Search the documentation of curl/wget for the term »netrc« to learn more details.

User/Password in URL

This is the easiest authentication method available. Please be aware that this authentication method does not provide sufficient measures to protect your credentials. For this reason, you have to specifically enable it per access key – this can be done in the customization pages.

Recognized parameters. 

NameDescriptionRequired
accesskey

The access key for the request sender. This parameter identifies the account that will be charged for the request. Access keys can be created in the API control panel. Additionally, the API control panel allows to set certain preferences and restrictions per access key.

Type: String

Example: NYczonwTxv

Yes
secretkey

The secret key associated with the access key.

Type: String

Example: x4whvXnG7cCOBiNBoi1r

Yes

Example Request. Assuming the following values, an example request is shown below:

Access key:
NYczonwTxv
Secret key:
x4whvXnG7cCOBiNBoi1r
Service name:
timeservice

http://api.xmltime.com/timeservice?accesskey=NYczonwTxv&secretkey=x4whvXnG7cCOBiNBoi1r&further parameters…

prev top | next >
Terms & ConditionsCopyright © Time and Date AS
All data supplied by timeanddate.com