Data Token Verification
How to verify and validate data tokens for security.
Token Verification
Data tokens are JWTs that must be verified before use:
from sva_oauth_client.utils import get_sva_claims
# Token is automatically verified
claims = get_sva_claims(request)
Verification Process
1. Signature Verification
The token signature is verified using the secret key:
import jwt
decoded = jwt.decode(
data_token,
DATA_TOKEN_SECRET,
algorithms=['HS256'],
options={
"verify_signature": True,
}
)
2. Expiration Verification
The token expiration is checked:
decoded = jwt.decode(
data_token,
DATA_TOKEN_SECRET,
algorithms=['HS256'],
options={
"verify_exp": True,
}
)
3. Audience Verification (Optional)
The audience claim can be verified:
decoded = jwt.decode(
data_token,
DATA_TOKEN_SECRET,
algorithms=['HS256'],
audience=CLIENT_ID, # Verify audience
options={
"verify_signature": True,
"verify_exp": True,
}
)
Automatic Verification
The get_sva_claims() function automatically verifies:
- Token signature
- Token expiration
- Token structure
from sva_oauth_client.utils import get_sva_claims
from sva_oauth_client.client import SVATokenError
try:
claims = get_sva_claims(request)
# Token is verified and valid
except SVATokenError:
# Token is invalid or expired
pass
Manual Verification
Verify Token Manually
from sva_oauth_client.client import get_client_from_settings
from sva_oauth_client.utils import get_data_token
def verify_token_manually(request):
"""Manually verify data token"""
data_token = get_data_token(request.session)
if not data_token:
return None
try:
client = get_client_from_settings()
decoded = client.decode_data_token(data_token)
return decoded
except SVATokenError:
return None
Token Structure Validation
Required Claims
Data tokens must contain:
sub- Subject (user ID)aud- Audience (client ID)auth_request_id- Authorization request IDclaims- User identity claimsexp- Expiration timeiat- Issued at time
Validate Structure
def validate_token_structure(decoded):
"""Validate token has required structure"""
required_claims = ['sub', 'aud', 'auth_request_id', 'claims', 'exp', 'iat']
for claim in required_claims:
if claim not in decoded:
raise ValueError(f"Missing required claim: {claim}")
if not isinstance(decoded['claims'], dict):
raise ValueError("Claims must be a dictionary")
return True
Security Checks
Signature Verification
Always verify the signature:
# ✅ Good - Verifies signature
decoded = jwt.decode(token, secret, algorithms=['HS256'])
# ❌ Bad - Doesn't verify signature
decoded = jwt.decode(token, options={"verify_signature": False})
Expiration Check
Always check expiration:
# ✅ Good - Checks expiration
decoded = jwt.decode(token, secret, algorithms=['HS256'])
# ❌ Bad - Doesn't check expiration
decoded = jwt.decode(token, secret, algorithms=['HS256'], options={"verify_exp": False})
Audience Validation
Validate audience matches your client:
# ✅ Good - Validates audience
decoded = jwt.decode(
token,
secret,
algorithms=['HS256'],
audience=CLIENT_ID
)
# ⚠️ Acceptable - Audience validation disabled (package default)
# The package disables audience validation by default
# because the audience may not match client_id in all cases
Error Handling
Invalid Token
from sva_oauth_client.client import SVATokenError
try:
claims = get_sva_claims(request)
except SVATokenError as e:
# Token is invalid
logger.warning(f"Invalid token: {e}")
# Handle error
Expired Token
from sva_oauth_client.client import SVATokenError
import jwt
try:
claims = get_sva_claims(request)
except jwt.ExpiredSignatureError:
# Token expired
logger.warning("Token expired")
# Handle expiration
except SVATokenError:
# Other token errors
pass
Best Practices
- Always verify - Never trust unverified tokens
- Check expiration - Tokens expire quickly (5 minutes)
- Validate structure - Ensure token has required claims
- Handle errors - Implement proper error handling
- Log failures - Monitor token verification failures
Configuration
Secret Key
# settings.py
SVA_DATA_TOKEN_SECRET = 'your-secret-key'
Important: Must match the secret configured in your SVA provider.
Algorithm
# settings.py
SVA_DATA_TOKEN_ALGORITHM = 'HS256' # or 'RS256'
Next Steps
- Learn about PKCE
- Understand CSRF Protection
- Read Security Best Practices