JWT Tokens
JSON Web Tokens (JWT) are the access tokens returned by Sesamy's Auth0-compatible authentication system. They provide stateless authentication for your API requests.
Overview
JWTs are compact, URL-safe tokens that contain encoded claims about a user or service. Sesamy issues JWTs as access tokens when you complete an authentication flow.
JWT Structure
A JWT consists of three parts separated by dots (.):
header.payload.signatureExample:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsImF6cCI6ImNsaWVudF9pZCIsImV4cCI6MTY5ODg1ODgwMH0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cHeader
Contains token type and signing algorithm:
{
"alg": "RS256",
"typ": "JWT",
"kid": "key_id"
}Sesamy uses RS256 (RSA) for signing, which means you can verify tokens using Sesamy's public key.
Payload
Contains claims (user or service data):
{
"sub": "user_123",
"aud": "https://api.sesamy.com",
"vendor_id": "vendor_456",
"iss": "https://token.sesamy.com/",
"exp": 1698858800,
"iat": 1698855200,
"email": "user@example.com",
"email_verified": true
}Signature
Cryptographically signed with Sesamy's private key to verify authenticity and integrity.
Obtaining a JWT
Via Authorization Code Flow
After completing an OAuth authorization code flow, you'll receive a JWT access token:
curl -X POST https://token.sesamy.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTHORIZATION_CODE" \
-d "client_id=YOUR_CLIENT_ID" \
-d "code_verifier=CODE_VERIFIER" \
-d "redirect_uri=https://yourapp.com/callback"Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "refresh_token_value"
}Via Refresh Token
When your access token expires, use the refresh token to obtain a new JWT:
curl -X POST https://token.sesamy.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=YOUR_CLIENT_ID" \
-d "refresh_token=REFRESH_TOKEN"Via Client Credentials Flow
For Management API access, you'll receive a JWT using client credentials:
curl -X POST https://token.sesamy.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "audience=https://api.sesamy.com"Using JWT Tokens
Include the JWT in the Authorization header of your API requests:
curl -X GET https://api.sesamy.com/client/v1/profile \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."SDK Examples
Since Sesamy uses Auth0-compatible authentication, you can use any Auth0-compatible SDK:
import { useAuth0 } from '@auth0/auth0-react';
import { useEffect, useState } from 'react';
function ProfileComponent() {
const { getAccessTokenSilently } = useAuth0();
const [profile, setProfile] = useState(null);
useEffect(() => {
const getProfile = async () => {
const token = await getAccessTokenSilently({
audience: 'https://api.sesamy.com',
scope: 'openid profile email'
});
const response = await fetch('https://api.sesamy.com/client/v1/profile', {
headers: { Authorization: `Bearer ${token}` }
});
setProfile(await response.json());
};
getProfile();
}, []);
return <div>{profile && <pre>{JSON.stringify(profile, null, 2)}</pre>}</div>;
}from auth0.authentication import GetToken
# Get token for Management API
get_token = GetToken('auth.sesamy.com')
token = get_token.client_credentials(
client_id='YOUR_CLIENT_ID',
client_secret='YOUR_CLIENT_SECRET',
audience='https://api.sesamy.com'
)
# Use token for API requests
import requests
headers = {'Authorization': f"Bearer {token['access_token']}"}
response = requests.get(
'https://api.sesamy.com/management/v1/publishers',
headers=headers
)Token Claims
Sesamy JWTs include these standard OpenID Connect claims:
| Claim | Description |
|---|---|
sub | Subject (unique user/service identifier) |
iss | Issuer (https://token.sesamy.com/) |
aud | Audience (https://api.sesamy.com for API access) |
vendor_id | Your vendor/publisher identifier |
exp | Expiration time (Unix timestamp) |
iat | Issued at (Unix timestamp) |
email | User's email address |
email_verified | Whether email is verified |
given_name | User's first name |
family_name | User's last name |
Validating JWTs
Server-Side Validation
Always validate JWTs on your server to ensure they're authentic:
- Verify Signature: Ensure the token is signed with Sesamy's key
- Check Expiration: Verify the
expclaim hasn't passed - Validate Issuer: Ensure
issishttps://token.sesamy.com/ - Validate Audience: Ensure
audishttps://api.sesamy.com - Check Vendor ID: Ensure
vendor_idclaim matches your vendor identifier
Sesamy uses RS256 (RSA) signing, so you'll need to fetch the public key from the JWKS endpoint:
curl https://token.sesamy.com/.well-known/jwks.jsonimport jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
const client = jwksClient({
jwksUri: 'https://token.sesamy.com/.well-known/jwks.json',
});
function getKey(header: any, callback: any) {
client.getSigningKey(header.kid, (err, key) => {
if (err) callback(err);
callback(null, key?.getPublicKey());
});
}
function validateToken(token: string) {
return new Promise((resolve, reject) => {
jwt.verify(
token,
getKey,
{
algorithms: ['RS256'],
issuer: 'https://token.sesamy.com/',
audience: 'https://api.sesamy.com',
},
(err, decoded) => {
if (err) reject(err);
resolve(decoded);
}
);
});
}import jwt
from functools import lru_cache
@lru_cache(maxsize=1)
def get_jwks():
import requests
return requests.get('https://token.sesamy.com/.well-known/jwks.json').json()
def validate_token(token: str):
import json
# Get the key ID from token header
unverified_header = jwt.get_unverified_header(token)
kid = unverified_header.get('kid')
# Get public key
jwks = get_jwks()
key = next((k for k in jwks['keys'] if k['kid'] == kid), None)
if not key:
raise ValueError('Key not found')
# Construct public key
from cryptography.hazmat.primitives import serialization
from jwcrypto import jwk
key_obj = jwk.JWK.from_json(json.dumps(key))
public_key = key_obj.serialize(private_key=False, as_dict=False)
# Verify token
try:
decoded = jwt.decode(
token,
public_key,
algorithms=['RS256'],
issuer='https://token.sesamy.com/',
audience='https://api.sesamy.com'
)
return decoded
except jwt.InvalidTokenError as e:
raise ValueError(f'Invalid token: {e}')Common Validation Issues
- "Invalid signature": Check that you're using the current public key from JWKS endpoint
- "Token expired": Use refresh tokens to obtain new access tokens
- "Invalid issuer": Verify issuer is
https://token.sesamy.com/ - "Invalid audience": Verify audience is
https://api.sesamy.com - "Invalid vendor_id": Ensure the
vendor_idclaim matches your vendor identifier
Token Refresh
When your JWT expires (typically after 1 hour), obtain a new one using your refresh token:
curl -X POST https://token.sesamy.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=YOUR_CLIENT_ID" \
-d "refresh_token=REFRESH_TOKEN"Best Practices
- Always validate on backend: Never trust tokens without validation
- Store securely: Use httpOnly, secure cookies or localStorage (with caution)
- Use refresh tokens: Implement automatic token refresh before expiration
- Never expose JWTs in URLs or logs: Keep tokens private
- Use HTTPS for all token transmission: Prevent interception
Security Considerations
Security
- Never expose JWTs in URLs or logs
- Always validate tokens on the server
- Use HTTPS for all token transmission
- Implement CSRF protection
- Rotate refresh tokens on use
Troubleshooting
Token Expired
Check the exp claim and refresh the token:
const decoded = jwt.decode(token);
if (decoded.exp * 1000 < Date.now()) {
// Token expired, refresh it
await refreshToken();
}Invalid Signature
- Verify you're using the correct public key
- Ensure the token hasn't been tampered with
- Check token isn't corrupted during transmission
Invalid Audience or Vendor ID
- Ensure the JWT's
audclaim ishttps://api.sesamy.com - Ensure the JWT's
vendor_idclaim matches your vendor identifier
Next Steps
- API Keys - Learn about API key authentication
- OAuth 2.0 - Understand OAuth flows
- API Reference - Explore API endpoints