Customer key authentication¶
To enable identification and personalisation across devices the class CustomerKeyAuthentication
must be implemented. Implementation examples are in NodeJS, C#, and Java. 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
- ThecustomerKey
signed with the private key,privateKey
(received from Voyado 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 behavior and notifications for the sites visitors.
Cookie properties¶
Property | Value | Description |
---|---|---|
Name | apptus.customerKey , or apptus.sessionKey , or apptus.token | See the section above for more information about each cookie. |
Path | / | The path is defined as the root of the Domain . |
Domain | Site host name | The Domain must match the host name of the site, for example www.example.com . |
Expires | Expiration date | The expiration date must be one year into the future. |
HttpOnly | N/A | The HttpOnly must not be specified as the Javascript Library interacts with the cookie. |
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 Elevate 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 Elevate 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 Voyado.</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 Elevate 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 Elevate 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 Voyado.
* @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());
}
}