Skip to content

Customer Key Authentication

To enable identification and personalisation across devices the class CustomerKeyAuthentication must be implemented. Implementation examples are in NodeJS, C#, Java, and PHP. This class requires Message Authentication to be implemented.

The following three cookies must be available once done.

  • apptus.sessionKey - A unique id. UUID / GUID.
  • apptus.customerKey - A SHA256 hash of the id of a signed in visitor.
  • apptus.token - The customerKey signed with the private key, privateKey (received from Apptus during the cloud configuration). This cookie should only be set for signed in visitors.

The reason both customerKey and token exist is that if the private key leaks or becomes public, it can be changed without losing behaviour and notifications for the sites visitors.

Usage

When a visitor signs in a customer key and an authorization token is to be generated server side. The authorization token is used to validate the customer key in the eSales Web API service.

It is recommended to use the visitor specific value and the private key during the customer key and token generation.

  • The customer key is to be set in the apptus.customerKey cookie.
  • The authorization token is to be set in the apptus.token cookie.

These cookies should live as long as the visitor is signed in, and by binding the sign out button/link to the endSession()-function in the JavaScript library they will be reset automatically.

Example

//Example in C#.
var auth = new CustomerKeyAuthentication("private-key", "user-name");
var customerKeyCookie = new HttpCookie("apptus.customerKey", auth.CustomerKey);
customerKeyCookie.Expires = DateTime.Now.AddYears(1);
var tokenCookie = new HttpCookie("apptus.token", auth.Token);
tokenCookie.Expires = DateTime.Now.AddYears(1);
Response.Cookies.Add(customerKeyCookie);
Response.Cookies.Add(tokenCookie);

Implementation

const crypto = require('crypto');
const ma = require('./messageAuthentication');

module.exports = (privateKey, user) => {
    const customerKey = crypto.createHash('sha256').update(user).digest('hex');
    const token = ma(privateKey).sign(customerKey);

    return {
        getCustomerKey() {
            return customerKey;
        },
        getToken() {
            return token;
        }
    }
};
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace Apptus.ESales.Connector
{
    public class CustomerKeyAuthentication
    {
        /// <summary>
        /// Creates a new instance that contains a personal customer key and a token, that can be used for
        /// cross-device client-side notifications in eSales Web API. This object should be created
        /// when the user has successfully logged in, and the respective values should be set in cookies.
        /// </summary>
        /// <param name="privateKey">A private key that is unique for this site. This key is provided by Apptus.</param>
        /// <param name="user">The user name, or other user-unique value, of the customer that logged in.</param>
        /// <exception cref="ArgumentException">If privateKey or user is null or empty.</exception>
        public CustomerKeyAuthentication(string privateKey, string user)
        {
            CustomerKey = Hash(user);
            Token = new MessageAuthentication(privateKey).Sign(CustomerKey);
        }

        /// <summary>
        /// A hash based on a user specific value, such as user name.
        /// This value should be stored in a cookie named "apptus.customerKey".
        /// </summary>
        public string CustomerKey { get; private set; }

        /// <summary>
        /// The signature of this customerKey.
        /// This value should be stored in a cookie named "apptus.token".
        /// </summary>
        public string Token { get; private set; }

        private static string Hash(string input)
        {
            return new SHA256Managed()
                .ComputeHash(Encoding.UTF8.GetBytes(input))
                .Aggregate(new StringBuilder(), (sb, b) => sb.AppendFormat("{0:x2}", b))
                .ToString();
        }
    }
}
package com.apptus.esales.connector;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * A class that should be used for creating personal customer keys when using eSales Web API.
 */
public class CustomerKeyAuthentication {

    private final String customerKey;
    private final String token;

    /**
     * Creates a new instance that contains a personal customer key and a token, that can be used for
     * cross-device client-side notifications in eSales Web API. This object should be created
     * when the user has successfully logged in, and the respective values should be set in cookies.
     * See {@link #getCustomerKey()} and {@link #getToken()}.
     * @param privateKey A private key that is unique for this site. This key is provided by Apptus.
     * @param user The user name, or other user-unique value, of the customer that logged in.
     * @throws IllegalArgumentException If privateKey or user is null or empty.
     **/
    public CustomerKeyAuthentication(String privateKey, String user) {
        customerKey = hash(user);
        token = new MessageAuthentication(privateKey).sign(customerKey);
    }

    /*
     * @return A hash based on a user specific value, such as user name.
     * This value should be stored in a cookie named "apptus.customerKey".
     */
    public String getCustomerKey() {
        return customerKey;
    }

    /**
     * @return The signature of this customerKey.
     * This value should be stored in a cookie named "apptus.token".
     */
    public String getToken() {
        return token;
    }

    private static String hash(String input) {
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            //it should not happen
            throw new RuntimeException(e);
        }
        md.reset();
        md.update(input.getBytes(StandardCharsets.UTF_8));
        return MessageAuthentication.toHexString(md.digest());
    }
}
<?php

namespace Apptus\ESales\Connector;

/**
 * A class that should be used for creating personal customer keys when using eSales Web API.
 */
class CustomerKeyAuthentication
{
    private $customerKey;
    private $token;

    /**
     * Creates a new instance that contains a personal customer key and a token, that can be used for
     * cross-device client-side notifications in eSales Web API. This object should be created
     * when the user has successfully logged in, and the respective values should be set in cookies.
     * See {@link getCustomerKey()} and {@link getToken()}.
     * @param $privateKey string A private key that is unique for this site. This key is provided by Apptus.
     * @param $user string The user name, or other user-unique value, of the customer that logged in.
     * @throws \InvalidArgumentException If privateKey or user is null or empty.
     */
    public function __construct($privateKey, $user)
    {
        $this->customerKey = hash('sha256', $user);
        $messageAuthentication = new MessageAuthentication($privateKey);
        $this->token = $messageAuthentication->sign($this->customerKey);
    }

    /**
     * @return string A hash based on a user specific value, such as user name.
     * This value should be stored in a cookie named "apptus.customerKey".
     */
    public function getCustomerKey()
    {
        return $this->customerKey;
    }

    /**
     * @return string The signature of this customerKey.
     * This value should be stored in a cookie named "apptus.token".
     */
    public function getToken()
    {
        return $this->token;
    }
}
×