Use a Server API Token With an Integration
- Applies to:
- All MindTouch Versions
- Role required:
- Admin
Prerequisites
What You'll Need
You should have recorded the following when generating your Server API Token:
- Key
- Secret
How to Use Your Server API Token
To gain access to the MindTouch API, you first need to provide a Server API Token signature to MindTouch. Your token signature will be in the following format:
tkn_{key}_{epoch}_{user}_{hash}
Server API Token Signature Breakdown
key |
Provided with your Server API Token |
epoch |
The current time in Unix timestamp (e.g. Current time: 02/03/2015 @ 5:10am (UTC); Unix timestamp: 1422940200) |
user |
A MindTouch user id or username prefixed with `=` (e.g. =admin). The API request will be handled in the context of this user identity |
hash |
MindTouch requires HMAC SHA256 hashing of server API tokens. The benefit of HMAC SHA256 over plain SHA256 is it provides MindTouch the ability to detect if the token signature has been tampered with since being generated by your server |
The signature is included in an API request by setting it as the X-Deki-Token
HTTP header value. Upon receipt, MindTouch calculates the same signature and matches it to the signature received. Once validated, your integration can access the MindTouch API.
Your signature is time-sensitive. If processed too long after the timestamp is generated, your request will be denied.
Examples
The following are code snippets for PHP, C#, Node.js, and Python to get you started:
Java Example
// Server API Token key and secret are available from API token management dashboard when Server API Token is generated String key = "dacaffe7ce69dfd1071531e925f667905a1c981fb40d06c676880e84352cb3aa"; String secret = "5b70319201e9abad12a3458b32ed30cf634ef569ea47906e5012baf11cab5046"; // include username prefixed with '=' String user = '=foo'; // ...or include userid String user = '123'; // hash time, key, user with secret String epoch = Long.toString(new Date().getTime() / 1000L); try { Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); String message = key + "_" + epoch + "_" + user; // this example uses Apache Commons Codec (https://commons.apache.org/proper/commons-codec/) to ensure bytes are converted to a HTTP header compatible hex string hash = Hex.encodeHexString(sha256_HMAC.doFinal(message.getBytes())); } catch (NoSuchAlgorithmException | InvalidKeyException e) { // handle signing exceptions } String token = String.join("_", "tkn", key, epoch, user, hash); // send signature as X-Deki-Token HTTP header to MindTouch API URL url = new URL("https://success.example.com/@api/deki/pages/home/info"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); con.setRequestProperty("X-Deki-Token", token);
PHP Example
<?php // Server API Token key and secret are available from API token management dashboard when Server API Token is generated $key = 'dacaffe7ce69dfd1071531e925f667905a1c981fb40d06c676880e84352cb3aa'; $secret = '5b70319201e9abad12a3458b32ed30cf634ef569ea47906e5012baf11cab5046'; // include username prefixed with '=' $user = '=foo'; // ...or include userid $user = '123'; // hash time, key, user with secret $epoch = time(); $hash = hash_hmac('sha256', ("{$key}_{$epoch}_{$user}"), $secret, false); $token = "tkn_{$key}_{$epoch}_{$user}_{$hash}"; // send signature as X-Deki-Token HTTP header to MindTouch API (a fictional HTTP client is used in this example) $client = new HttpClient('https://success.example.com/@api/deki/pages/home/info'); $client = $client->withHeader('X-Deki-Token', $token); $response = $client->get();
C# Example
using System; using System.IO; using System.Security.Cryptography; using System.Net.Http; // Server API Token key and secret are available from API token management dashboard when Server API Token is generated var key = "da28b6ec3ea350db524d80099f8c9f40f2fab2f4caf91a8d49d4cb4d659a9785"; var secret = "60a63916a77ef70c0ecf42b134f44fbb9732b395ae33dc6d5165aad2b5668bb4"; // include username prefixed with '=' var user = "=admin"; // ...or include userid user = "1"; // hash time, key, user with secret var hash = ""; var epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; using (var hmac = new HMACSHA256(Encoding.ASCII.GetBytes(secret))) { var bytes = hmac.ComputeHash(Encoding.ASCII.GetBytes(string.Format("{0}_{1}_{2}", key, epoch, user))); hash = BitConverter.ToString(bytes).Replace("-", ""); } var signature = string.Format("tkn_{0}_{1}_{2}_{3}", key, epoch, user, hash); // send signature as X-Deki-Token HTTP header to MindTouch API (WebRequest is used in this example) var client = new HttpClient(); client.DefaultRequestHeaders.Add("X-Deki-Token", signature); var response = await client.GetAsync("https://authtalk.mindtouch.es/@api/deki/users/current?dream.out.format=json"); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); // Exchange signature token for a user's authtoken for immediate access via a link. // https://{authtalk.mindtouch.es}/@api/deki/users/authenticate?x-deki-token={signature} Console.WriteLine($"https://authtalk.mindtouch.es/@api/deki/users/authenticate?x-deki-token={signature}"); Console.WriteLine($"https://authtalk.mindtouch.es/@api/deki/users/authenticate?x-deki-token={signature}&redirect=https%3A%2F%2Fauthtalk.mindtouch.es%2F");
Node.js Example
// Server API Token key and secret are available from API token management dashboard when Server API Token is generated const key = 'dacaffe7ce69dfd1071531e925f667905a1c981fb40d06c676880e84352cb3aa'; const secret = '5b70319201e9abad12a3458b32ed30cf634ef569ea47906e5012baf11cab5046'; // include username prefixed with '=' let user = '=foo'; // ...or include userid let user = '123'; // hash time, key, user with secret const crypto = require('crypto'); const hmac = crypto.createHmac('sha256', secret); const epoch = Math.floor(Date.now() / 1000); hmac.update(`${key}_${epoch}_${user}`); const hash = hmac.digest('hex'); const token = `tkn_${key}_${epoch}_${user}_${hash}`; // send signature as X-Deki-Token HTTP header to MindTouch API (https://github.com/request/request is used in this example) const request = require('request'); request({ url: 'https://success.example.com/@api/deki/pages/home/info', headers: { 'X-Deki-Token': token } }, (error, response, body) => { // ... });
Python 3 Example
# Server API Token key and secret are available from API token management dashboard when Server API Token is generated key = 'dacaffe7ce69dfd1071531e925f667905a1c981fb40d06c676880e84352cb3aa' secret = '5b70319201e9abad12a3458b32ed30cf634ef569ea47906e5012baf11cab5046' # include username prefixed with '=' user = '=foo'; # ...or include userid user = '123'; # hash time, key, user with secret epoch = str(int(time.time())) message_bytes = bytes(key + '_' + epoch + '_' + user) secret_bytes = bytes(secret) hash = hmac.new(secret_bytes, message_bytes, digestmod=hashlib.sha256).hexdigest().lower() token = 'tkn_' + key + '_' + epoch_time + '_' + user + '_' + hashed_value # send signature as X-Deki-Token HTTP header to MindTouch API (Python Requests is used in this example) headers = { 'X-Deki-Token': token, } r = requests.get('https://success.example.com/@api/deki/pages/home/info', headers=headers, verify=False)
Postman Example
In pre-request script:
// Server API Token key and secret are available from API token management dashboard when Server API Token is generated const key = 'dacaffe7ce69dfd1071531e925f667905a1c981fb40d06c676880e84352cb3aa'; const secret = '5b70319201e9abad12a3458b32ed30cf634ef569ea47906e5012baf11cab5046'; // include username prefixed with '=' let user = '=admin'; // ...or include userid let user = '123'; // hash time, key, user with secret const epoch = Math.floor(Date.now() / 1000); var hash = CryptoJS.HmacSHA256(`${key}_${epoch}_${user}`, secret); const token = `tkn_${key}_${epoch}_${user}_${hash}`; pm.globals.set("token", token);
In Headers, create a key x-deki-token
and set the value to {{token}}
.
Authenticate With a Server API Token
This authentication method should only be used to implement Single Sign-On if it is not possible to leverage MindTouch's supported enterprise-grade OpenID Connect or SAML SSO solutions.
A Server API Token signature can be traded for an Auth Token session cookie, which will sign in a user. Using this method, you can construct a URI that logs the user in and redirects to any page in MindTouch. To tell the API to issue an Auth Token session cookie, use the following format to create a URI for the user to follow:
GET https://{hostname}/@api/deki/users/authenticate?x-deki-token={signature}&redirect={redirect}
{hostname}
is the hostname of the MindTouch site{signature}
is the server API token signature{redirect}
is a URI for the user to be redirected to (e.g. redirect=https://example.com/foo). This URI must be URI encoded
Since this URI is valid for only a few minutes, it should not be generated as a URI on one of your pages directly. Instead, it should be a redirect response of a request to your server that authenticates the user in your system. The system should build the URI at the time of request. After the user follows the URI, if the authentication is successful they receive HTTP response headers similar to the following:
HTTP/1.1 302 FOUND Date: Thu, 28 Feb 2013 19:58:59 GMT Server: Dream-HTTPAPI/2.4.0.393 X-Deki-Site: id="{site}" X-Deki-Session: {session} Content-Type: text/plain; charset=us-ascii Content-Length: 20 Location: {redirect} Set-Cookie: authtoken="{authtoken}"; Domain=.{hostname}; Set-Cookie: dekisession="{session}"; Domain=.{hostname};
This results in a sign in workflow like this:
- A user logged into your authentication system clicks a URI to go to the MindTouch site. Note: the URL actually points to an endpoint on your site.
- Your endpoint validates the user's credentials.
- Your endpoint constructs the Server API Token signature and the redirect URI above.
- Your endpoint responds with a
302 Found
response and the constructed URI as itsLocation
Header. - The user's browser redirects to the MindTouch API.
- The MindTouch API creates the user as a Community Member if they do not exist on MindTouch site, and issues a
302 Found
response including the Auth Token session cookie and theLocation
Header for{redirect}
.