JSON Web Tokens (JWTs)
A JSON Web Token, or JWT, is an open standard for securely sharing information as a JSON object. JWTs are small enough to be used in a GET or POST parameter or an HTTP header, and because they are digitally signed, the information inside can be trusted.
JWTs can be generated using a library. Options can be found on JWT.io or GitHub.
Step 1: Collect the data object
Whether you are using a JWT with UTT or the Open Endpoints, you will need to start with the data object that you are trying to sign.
For Advocate implementations, id
and accountId
will always be set to the same thing.
{
"id": "[email protected]", //This field will be dependent on your implementation
"accountId": "[email protected]", //This field will be dependent on your implementation
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"locale": "en_US",
}
Step 2: Assemble the JWT payload
The JWT payload structures the data trying to be signed in this format:
For Advocate implementations, id
and accountId
will always be set to the same thing.
{
"user":{
"id": "[email protected]", //This field will be dependent on your implementation
"accountId": "[email protected]", //This field will be dependent on your implementation
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"locale": "en_US",
}
}
Step 3: Sign the payload
Use your chosen library to build the JWT with the payload, and sign it with your API key and Auth Token.
// Example uses jose-jwt: https://github.com/dvsekhvalnov/jose-jwt
using System.Collections.Generic;
using System.Text;
using Jose;
namespace JwtExample
{
class Jwt
{
// An example for building a user JWT.
// accountSid/authToken - your impact.com API credentials
// userId - your unique identifier for this user
public static string buildJwt(string accountSid, string authToken, string userId, string email, string firstName, string lastName)
{
// Build the user payload. Most fields are optional, but id and accountId are required
// and are set to the same value. See the API documentation for more fields that you
// can add to your users.
var userPayload = new Dictionary<string, object>() {
{ "id", userId }, // required
{ "accountId", userId }, // required
{ "firstName", firstName }, // optional
{ "lastName", lastName }, // optional
{ "email", email } // optional
};
// Expiry date is optional, but recommended
var expiryDate = ((DateTimeOffset)DateTime.UtcNow.Date.AddDays(7)).ToUnixTimeSeconds();
var payload = new Dictionary<string, object>() {
{ "user", userPayload },
{ "exp", expiryDate }
};
var headers = new Dictionary<string, object>() {
{ "typ", "JWT" },
{ "kid", accountSid }
};
var byteSecret = Encoding.UTF8.GetBytes(authToken);
return Jose.JWT.Encode(payload, byteSecret, JwsAlgorithm.HS256, extraHeaders: headers);
}
}
}
# Example uses ruby-jwt: https://github.com/jwt/ruby-jwt
require "jwt"
# An example for building a user JWT.
# accountSid/authToken - your impact.com API credentials
# userId - your unique identifier for this user
def buildJwt(accountSid, authToken, userId, email, firstName, lastName)
# Build the user payload. Most fields are optional, but id and accountId are required
# and are set to the same value. See the API documentation for more fields that you
# can add to your users.
userPayload = {
id: userId, # required
accountId: userId, # required
firstName: firstName, # optional
lastName: lastName, # optional
email: email, # optional
}
# Expiry date is optional, but recommended
expiryDate = Time.now.to_i + 7 * 24 * 3600
payload = {
user: userPayload,
exp: expiryDate,
}
headers = {
typ: "JWT",
kid: accountSid,
}
return JWT.encode(payload, authToken, algorithm = "HS256", header_fields = headers)
end
// Example uses nimbus-jose-jwt: https://bitbucket.org/connect2id/nimbus-jose-jwt/src/master/
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
public class Jwt {
// An example for building a user JWT.
// accountSid/authToken - your impact.com API credentials
// userId - your unique identifier for this user
public static String buildJwt(String accountSid, String authToken, String userId, String email, String firstName, String lastName) {
// Build the user payload. Most fields are optional, but id and accountId are required
// and are set to the same value. See the API documentation for more fields that you
// can add to your users.
final Map<String, Object> userPayload = new HashMap<>();
userPayload.put("id", userId); // required
userPayload.put("accountId", userId); // required
userPayload.put("firstName", firstName); // optional
userPayload.put("lastName", lastName); // optional
userPayload.put("email", email); // optional
// Expiry date is optional, but recommended
Date expiryDate = Date.from(Instant.now().plus(Duration.ofDays(7)));
final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
.claim("user", userPayload)
.expirationTime(expiryDate)
.build();
final JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.HS256)
.type(JOSEObjectType.JWT)
.keyID(accountSid)
.build();
final SignedJWT jwt = new SignedJWT(header, claimsSet);
try {
jwt.sign(new MACSigner(authToken));
} catch (JOSEException e) {
// This will happen if your secret is shorter than 256 bits.
// If you are using your Impact API keys, you won't need to worry about it.
throw new RuntimeException(e);
}
return jwt.serialize();
}
}
// Example uses php-jwt: https://github.com/firebase/php-jwt
use Firebase\JWT\JWT;
// An example for building a user JWT.
// accountSid/authToken - your impact.com API credentials
// userId - your unique identifier for this user
function buildJwt($accountSid, $authToken, $userId, $email, $firstName, $lastName)
{
// Build the user payload. Most fields are optional, but id and accountId are required
// and are set to the same value. See the API documentation for more fields that you
// can add to your users.
$userPayload = [
"id" => $userId, // required
"accountId" => $userId, // required
"firstName" => $firstName, // optional
"lastName" => $lastName, // optional
"email" => $email, // optional
];
// Expiry date is optional, but recommended
$now = new DateTime();
$expiryDate = $now->add(new DateInterval('P7D'))->getTimestamp();
$payload = [
"user" => $userPayload,
"exp" => $expiryDate
];
$headers = [
"typ" => "JWT",
"kid" => $accountSid
];
return JWT::encode($payload, $authToken, 'HS256', null, $headers);
}
# Example uses PyJWT: https://github.com/jpadilla/pyjwt/
import time
import jwt
# An example for building a user JWT.
# accountSid/authToken - your impact.com API credentials
# userId - your unique identifier for this user
def buildJwt(accountSid, authToken, userId, email, firstName, lastName):
# Build the user payload. Most fields are optional, but id and accountId are required
# and are set to the same value. See the API documentation for more fields that you
# can add to your users.
userPayload = {
'id': userId, # required
'accountId': userId, # required
'firstName': firstName, # optional
'lastName': lastName, # optional
'email': email # optional
}
# Expiry date is optional, but recommended
expiryDate = time.time() + 7 * 24 * 3600
payload = {
'user': userPayload,
'exp': expiryDate
}
headers = {
'typ': 'JWT',
'kid': accountSid
}
return jwt.encode(payload, authToken, algorithm='HS256', headers=headers)
For other fields that can be included in user objects, visit the User Upsert API documentation.
Step 4: Include the JWT with your calls
After creating a JWT, it must be included with all of your calls.
UTT
Here’s an example of how a UTT call that includes the JWT would appear:
<script>
window.impactToken = “JWT_GOES_HERE”
</script>
<impact-embed widget=”p/program-id/w/referrerWidget”></impact-embed>
Open Endpoint API Call
For Open Endpoint API calls, the JWT must be included as a header with the key X-SaaSquatch-User-Token
. cURL uses the -H
flag to pass an extra header. You may specify any number of extra headers.
Note:
Open Endpoint API calls made from a server should be signed with your API key. Only Open Endpoint calls from a client should be signed with a JWT.
curl -X POST <https://app.referralsaasquatch.com/api/v1/{tenant_alias}/open/account/{accountId}/user/{userId}>
-H "X-SaaSquatch-User-Token: {X-SaaSquatch-User-Token}"
-H "Content-Type: application/json"
-d '{
"id": "[email protected]",
"accountId": "[email protected]",
"email": "[email protected]",
"firstName": "Joe",
"lastName": "Testerson",
"locale": "en_US",
"referralCode": "JOETESTERSON"
}'
Updated 3 months ago