Signature Verification
Overview
To ensure the authenticity of embedded sections, Fourthwall uses HMAC-SHA512 signatures to prove that the content is being embedded on a Fourthwall shop, for a specific supporter and tier.
The following parameters are passed to your iframe:
hmac
: The HMAC signature.
timestamp
: The timestamp of when the signature was generated.
shop_id
: Your shop id. You can verify your shop id here
supporter_id
: Supporter id of the supporter logged into memberships. You can verify your supporter id here
tier_id
: Tier id of the tier the supporter is subscribed to. You can verify your tier id here
Verification
To verify the signature, you will recalculate the HMAC signature using the same parameters and your secret key.
"shop_id=#{shop_id}&supporter_id=#{supporter_id}&tier_id=#{tier_id}×tamp=#{timestamp}"
Your secret key is available in your Developer settings
Once verified, you can use the parameters to gate content. For example, you can show a different message to supporters based on their tier.
JavaScript Example
async function getHmacKey(secret: string): Promise<CryptoKey> {
const encoder = new TextEncoder();
const keyData = encoder.encode(secret);
return await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'HMAC', hash: 'SHA-512' },
false,
['sign', 'verify']
);
}
export async function verifySignature(params: {
shopId: string,
supporterId: string,
tierId: string,
timestamp: string,
}, hmacSignature: string, secret: string): Promise<boolean> {
const { shopId, supporterId, tierId, timestamp } = params;
const encoder = new TextEncoder();
const key = await getHmacKey(secret);
// Construct the data string from the individual fields
const data = `shop_id=${shopId}&supporter_id=${supporterId}&tier_id=${tierId}×tamp=${timestamp}`;
// Generate the HMAC for the constructed data
const messageData = encoder.encode(data);
const signature = await crypto.subtle.sign(
'HMAC',
key,
messageData
);
// Convert the generated signature to hex
const generatedSignatureHex = uint8ArrayToHex(new Uint8Array(signature));
// Compare the hex signatures
return generatedSignatureHex === hmacSignature;
}