The idea of Stateless SSO is simple: Each time the <hyvor-talk-comments>
element loads, you will let us know if the user is logged in or not. If yes, you will also send the user's data along with other configuration. An HMAC hash is used to validate the authenticity of user data.
To enable Stateless SSO on your website, turn on SSO from the Console, and select the type Stateless. A Private key will be generated for you. You will need this key to generate the HMAC hash in the next steps.
If you have a login page, set the Login URL to the URL of your login page. This will be used to redirect users when they click on the login button. If you have a login popup, keep the Login URL option empty and use the auth:login:clicked
event to open the popup using Javascript.
To set up Stateless SSO, you have to set sso-user
and sso-hash
attributes in the <hyvor-talk-comments>
element.
If you are using HTML installation,
<hyvor-talk-comments
...other-props
sso-user="base-64 encoded, JSON-encoded user data"
sso-hash="HMAC hash"
></hyvor-talk-comments>
If you are using JS installation,
const comments = document.createElement("hyvor-talk-comments");
comments.setAttribute('sso-user', "base-64 encoded, JSON-encoded user data");
comments.setAttribute('sso-hash', "HMAC hash");
If your website is rendered using templates with back-end processing (for example, using PHP templates), you can calculate the data and hash at the time of template rendering, and then print them directly in the HTML code
<hyvor-talk-comments
...other-props
sso-user="<?= $userData ?>"
sso-hash="<?= $hash ?>"
></hyvor-talk-comments>
If you have a Single-Page application, you will need to create a new API endpoint (ex: /hyvor-talk-sso
) to generate the data and hash in your backend. Then, call that endpoint to get the hash and then render the <hyvor-talk-comments>
element asynchronously.
const comments = document.createElement("hyvor-talk-comments");
const ssoData = await getHyvorTalkSsoData(); // calling the API
comments.ssoUser = ssoData.user;
comments.ssoHash = ssoData.hash;
// finally add the element to DOM
document.body.appendChild(comments);
Whether you generate user data and the hash synchronously or asynchronously, the process will always be the same. In this documentation, we will use Javascript as most web developers are familiar with it. You can find code examples for other languages in this repository.
if (isUserLoggedIn()) {
}
Handling Unauthenticated Users
If the user is not logged in, you can stop doing any other processing. In the comments element, set
sso-user
andsso-hash
to empty values:
sso-user=””
in HTMLcomments.setAttribute('sso-user', null)
in JS (or any other empty value)
You may already have the current user’s data in your system as an object or model. The next step is to convert that into an object that Hyvor Talk "understands".
// this is your system's user
const user = getUser();
// create an object that Hyvor Talk understands
let userData = {
timestamp: Math.floor(Date.now() / 1000),
id: user.id,
name: user.fullname,
email: user.email,
picture_url: user.picture,
website_url: user.website,
bio: user.bio,
location: user.location,
badge_ids: [1,2]
}
Key | Description | Type | Status | Max Length |
---|---|---|---|---|
timestamp |
UNIX timestamp in seconds when the object was created. | integer |
required | |
id |
A unique ID saved in your database for each user. This is used to identify each user by Hyvor Talk. | integer or string |
required | 128 |
name |
User's display name | string |
required | 50 |
email |
User's email | string |
required | 256 |
picture_url |
Absolute URL of the user's profile picture | string |
optional | 1024 |
website_url |
Absolute URL of the user's profile or website | string |
optional | 1024 |
bio |
User’s bio | string |
optional | 255 |
location |
User’s country or city. | string |
optional | 50 |
badge_ids |
An array of badge IDs to assign to this user | integer[] |
optional | max 3 IDs |
Data Length
id
,picture_url
, andwebsite_url
should not exceed the maximum length. This will show an error message and prevent the embed from loading. Ifname
,bio
, orlocation
exceeds the maximum length, they will be trimmed.
Data Privacy
The
name
,picture_url
,website_url
,bio
, andlocation
will be shown publicly. The
Next, JSON-encode and then base64-encode the user data.
// 1. JSON encoding
userData = JSON.stringify(userData);
// 2. Base64 encoding
userData = Buffer.from(userData).toString('base64');
Why JSON and Base64?
JSON encoding makes transmitting data through networks easy. Base64 encoding makes it possible to print out this data into HTML code. Therefore, JSON and base64 encoding is for convenience, not for security.
The next step is to generate an HMAC hash from userData. For this, we need the private key you received when setting up Stateless SSO in the Console. We use HMAC SHA 256.
Here we will use the crypto-js
Javascript library. However, most programming languages have HMAC hashing functions in-built.
const CryptoJS = require('crypto-js');
const hash = CryptoJS.HmacSHA256(userData, YOUR_PRIVATE_KEY);
Why the hash?
In order to securely connect SSO, we need to make sure that we receive the SSO user data generated by you, not someone else. The hash ensures this. Because the private key is only shared between you and us, no one else can generate a valid HMAC hash. So, when we render the
<hyvor-talk-comments>
element, we check if the user data and hash match. And, only then, do we log in the user.
Why
timestamp
in the user object?This is a metadata that allows us to expire old objects. For example, if a SSO hash is ever compromised, it will not be an issue as the timestamp is included. If we receive an timestamp older than 60 seconds, the user will not be logged in - an error will be shown. 60 seconds is more than enough from the time the hash is generated to the time
<hyvor-talk-comments>
’s first internal API call is made.
Here’s the complete code in JS (Node):
if (isUserLoggedIn()) {
// this is your system's user
const user = getUser();
// create an object that Hyvor Talk understands
let userData = {
id: user.id,
name: user.fullname,
email: user.email,
picture_url: user.picture,
website_url: user.website
}
// 1. JSON encoding
userData = JSON.stringify(userData);
// 2. Base64 encoding
userData = Buffer.from(userData).toString('base64');
// HMAC SHA256 hash
const CryptoJS = require('crypto-js');
const hash = CryptoJS.HmacSHA256(userData, YOUR_PRIVATE_KEY);
}
The last step is to set the attributes in the <hyvor-talk-comments>
element.
sso-user
to the userData
variable.sso-hash
to the hash
variable..env
. Do not commit it to source control.POST
HTTP method.