Server Authentication
Secure user identification with HMAC-SHA256 signatures.
Overview
By default, user identification is trust-based — anyone with your project ID could identify as any user. Secure Mode adds server-side verification to prevent identity spoofing.
When enabled, the SDK requires an HMAC-SHA256 signature generated on your server for every identify call. The signature is computed by hashing the user's ID with your workspace's secret key.
Enable Secure Mode from Settings > Login & SSO. Once enabled, identify calls without a valid signature will be rejected.
Get your secret key
Your secret signing key is in the JotReview dashboard under Settings > Login & SSO.
Keep this key private — it should only exist on your server, never in client-side code or bundled into your app. Rotate it immediately if you believe it has been compromised.
The key is a 32-byte hex string that looks like:
Node.js implementation
The signing logic is identical regardless of which client SDK you use — hash the user ID with your secret key and return the hex digest:
const JOTREVIEW_SECRET = process.env.JOTREVIEW_SECRET_KEY;
function generateSignature(userId) { return crypto .createHmac('sha256', JOTREVIEW_SECRET) .update(userId) .digest('hex'); }
// Express endpoint
app.get('/api/jotreview-signature', requireAuth, (req, res) => {
const signature = generateSignature(req.user.id);
res.json({ signature });
});
`
Python implementation
JOTREVIEW_SECRET = os.environ['JOTREVIEW_SECRET_KEY']
def generate_signature(user_id: str) -> str: return hmac.new( JOTREVIEW_SECRET.encode('utf-8'), user_id.encode('utf-8'), hashlib.sha256 ).hexdigest()
# Django view from django.http import JsonResponse from django.contrib.auth.decorators import login_required
@login_required
def jotreview_signature(request):
signature = generate_signature(str(request.user.id))
return JsonResponse({'signature': signature})
`
React Native implementation with signature
Fetch the signature from your server and pass it to JotReview.identify. Never compute the signature on the device.
async function handleSuccessfulLogin(user) {
// Fetch signature from your backend
const res = await fetch("https://api.yourapp.com/jotreview-signature", {
headers: { Authorization: Bearer ${user.accessToken} },
});
const { signature } = await res.json();
// Identify with the server-generated signature
JotReview.identify({
userId: user.id,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
signature,
});
}
`
If the signature is invalid, JotReview falls back to anonymous mode and logs a warning. Enable Strict Mode in Settings > Login & SSO to reject the session entirely instead of falling back.