Growth or above plan is required.
- Log in to acquire your private key from SSO settings. Ensure that you store this key securely on your server and prevent unauthorized access.
- When a user visits the widget, send a request to your server to generate a JWT token.
- Generate a token on your server with customer data using the provided snippet.
- Pass the generated JWT token to the Supahub widget for authentication.
SSO Setup
1
Install JWT packages
Install the required packages for JWT token generation on your server.
npm install --save jsonwebtoken
pip install pyjwt
// Instructions here
https://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/
// Instructions here
https://github.com/jwtk/jjwt#install
go get github.com/golang-jwt/jwt
composer require firebase/php-jwt
2
Generate the JWT token
Copy and use the “Private Key” from SSO settings to generate a JWT token on your server.
var jwt = require("jsonwebtoken");
const SSO_KEY = "YOUR_PRIVATE_SSO_KEY";
function generateJWTToken(user) {
var userData = {
email: user.email, // Required
name: user.name, // Required
id: user.id, // Required
};
// The userData object can include any additional details you wish to provide about a user to Supahub. Ensure to follow the same format shown in the Supahub.identify method, as outlined at https://docs.supahub.com/identify/user
return jwt.sign(userData, SSO_KEY, {
algorithm: "HS256",
});
}
import jwt
from datetime import datetime, timedelta
SSO_KEY = "YOUR_PRIVATE_SSO_KEY"
def generate_JWT_token(user):
userData = {
'email': user['email'], # Required
'name': user['name'], # Required
'id': user['id'], # Required
}
# The userData object can include any additional details you wish to provide about a user to Supahub. Ensure to follow the same format shown in the Supahub.identify method, as outlined at https://docs.supahub.com/identify/user
return jwt.encode(userData, SSO_KEY, algorithm='HS256')
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
public string GenerateJwtToken(User user)
{
var claims = new[]
{
new Claim("email", user.email), // Required
new Claim("name", user.name), // Required
new Claim("id", user.id), // Required
};
// The userData object can include any additional details you wish to provide about a user to Supahub. Ensure to follow the same format shown in the Supahub.identify method, as outlined at https://docs.supahub.com/identify/user
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YOUR_PRIVATE_SSO_KEY"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
claims: claims,
signingCredentials: creds);
return new JwtSecurityTokenHandler().WriteToken(token);
}
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
String SSO_KEY = "YOUR_PRIVATE_SSO_KEY";
public String generateJwtToken(User user) {
Map<String, Object> claims = new HashMap<>();
claims.put("email", user.getEmail()); // Required
claims.put("name", user.getName()); // Required
claims.put("id", user.getId()); // Required
// The userData object can include any additional details you wish to provide about a user to Supahub. Ensure to follow the same format shown in the Supahub.identify method, as outlined at https://docs.supahub.com/identify/user
return Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS256, SSO_KEY)
.compact();
}
import (
"github.com/golang-jwt/jwt",
)
var SSO_KEY = []byte("YOUR_PRIVATE_SSO_KEY")
func GenerateJwtToken(user User) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"email": user.email, // Required
"name": user.name, // Required
"id": user.id, // Required
})
// The userData object can include any additional details you wish to provide about a user to Supahub. Ensure to follow the same format shown in the Supahub.identify method, as outlined at https://docs.supahub.com/identify/user
return token.SignedString([]byte(PrivateKey));
}
use FirebaseJWTJWT;
$SSO_KEY = "YOUR_PRIVATE_SSO_KEY";
function generateJwtToken($user) {
$payload = array(
"email" => $user['email'], // Required
"name" => $user['name'], // Required
"id" => $user['id'], // Required
);
// The userData object can include any additional details you wish to provide about a user to Supahub. Ensure to follow the same format shown in the Supahub.identify method, as outlined at https://docs.supahub.com/identify/user
return JWT::encode($payload, $SSO_KEY);
}
Private Key should be kept secure and not to be shared. Add it in your .env
file.
To enhance security measures, Single Sign-On (SSO) tokens are restricted from authenticating users with administrative privileges within any Supahub workspace. Instead, these users will need to log in using the dedicated portal at workspace.supahub.com
3
Pass the token back to your app and into our widget
The token will be used for user authentication.
<script id="supahub" type="text/javascript">
!(function (s, u, p, a) {
function supahub() {
var g = u.createElement(p),
h = u.getElementsByTagName(p)[0];
(g.id = a),
(g.src = "https://widget.supahub.com/sdk.js"),
h.parentNode.insertBefore(g, h);
g.onload = function () {
window.SupahubWidget("portal", {
workspaceName: "workspace-name", // Required: Copy your workspace name from 'workspace-name.supahub.com'
theme: "light", // Required: Options ("dark" | "light")
displayType: "popover", // Required: Options ("popover" | "popup")
position: "right", // Optional: Options ("right" | "left")
jwtToken: "Generated_JWT_Token", // Optional: Replace with the token generated from your server
});
};
}
"function" != typeof s.SupahubWidget &&
(s.SupahubWidget = function () {
(s.SupahubWidget.q = s.SupahubWidget.q || []).push(arguments);
}),
"complete" === u.readyState || "interactive" === u.readyState
? supahub()
: s.addEventListener("DOMContentLoaded", supahub);
})(window, document, "script", "supahub-sdk");
</script>
"use client"; // NextJS 13 requires this. Remove if you are using NextJS 12 or lower.
import Script from "next/script";
const AllInOneWidget = () => {
return (
<>
<Script id="supahub" strategy="afterInteractive" type="text/javascript">
{`!(function (s, u, p, a) {
function supahub() {var g=u.createElement(p),h=u.getElementsByTagName(p)[0];(g.id=a),(g.src="https://widget.supahub.com/sdk.js"),h.parentNode.insertBefore(g, h);
g.onload = function () {
window.SupahubWidget("portal", {
workspaceName: "workspace-name", // Required: Copy your workspace name from 'workspace-name.supahub.com'
theme: "light", // Required: Options ("dark" | "light")
displayType: "popover", // Required: Options ("popover" | "popup")
position: "right", // Optional: Options ("right" | "left")
jwtToken: "Generated_JWT_Token", // Optional: Replace with the token generated from your server
});
}};
"function"!=typeof s.SupahubWidget&&(s.SupahubWidget=function(){(s.SupahubWidget.q=s.SupahubWidget.q||[]).push(arguments);}),"complete"===u.readyState||"interactive"===u.readyState?supahub():s.addEventListener("DOMContentLoaded", supahub);
})(window, document, "script", "supahub-sdk");`}
</Script>
</>
);
};
export default AllInOneWidget;
<script lang="ts" setup>
import { onMounted } from "vue";
onMounted(() => {
if (document.getElementById("supahub-sdk")) {
return;
}
const script = document.createElement("script");
script.id = "supahub-sdk";
script.src = "https://widget.supahub.com/sdk.js";
script.async = true;
script.onload = () => {
const win: any = window;
win.SupahubWidget("portal", {
workspaceName: "workspace-name", // Required: Copy your workspace name from 'workspace-name.supahub.com'
theme: "light", // Required: Options ("dark" | "light")
displayType: "popover", // Required: Options ("popover" | "popup")
position: "right", // Optional: Options ("right" | "left")
jwtToken: "Generated_JWT_Token", // Optional: Replace with the token generated from your server
});
};
document.head.appendChild(script);
});
</script>
<template>
<h1>This is a component</h1>
</template>
<style>
...
</style>