Custom Scopes
How to request and handle custom identity blocks (scopes).
Requesting Custom Scopes
In Settings
Configure default scopes in settings.py:
# settings.py
SVA_OAUTH_SCOPES = 'openid email profile username name phone address bio social images'
Dynamically
Request scopes dynamically per request:
from sva_oauth_client.client import SVAOAuthClient
from django.conf import settings
def login_with_custom_scopes(request, scopes):
"""Login with custom scopes"""
client = SVAOAuthClient(
base_url=settings.SVA_OAUTH_BASE_URL,
client_id=settings.SVA_OAUTH_CLIENT_ID,
client_secret=settings.SVA_OAUTH_CLIENT_SECRET,
redirect_uri=settings.SVA_OAUTH_REDIRECT_URI,
data_token_secret=settings.SVA_DATA_TOKEN_SECRET,
scopes=scopes, # Custom scopes
)
auth_url, code_verifier = client.get_authorization_url()
request.session['code_verifier'] = code_verifier
return redirect(auth_url)
Available Scopes
Core Identity
openid- Required for OIDCemail- Email addressprofile- Basic profile (name, username, bio, images)username- Usernamename- Full namebio- Bio/descriptionpronoun- Pronounsdob- Date of birth
Contact Information
phone- Phone numberaddress- Address informationsocial- Social media links
Profile Information
images- Profile imagesskills- Skills listhobby- Hobbies
Verified Identity Documents
pan_card- PAN cardaadhar- Aadhaar carddriving_license- Driving licensevoter_id- Voter IDpassport- Passport
Professional Information
education- Education historyemployment- Employment historyprofessional_license- Professional licenses
Financial Information
crypto_wallet- Crypto wallet addresses
Scope Combinations
Basic Profile
SVA_OAUTH_SCOPES = 'openid email profile'
Gets: email, name, username, bio, images
Complete Profile
SVA_OAUTH_SCOPES = 'openid email profile username name phone address bio social images'
Gets: All profile information
Professional Profile
SVA_OAUTH_SCOPES = 'openid email profile name phone education employment professional_license'
Gets: Professional information
Identity Verification
SVA_OAUTH_SCOPES = 'openid email profile pan_card aadhar driving_license'
Gets: Verified identity documents
Handling Custom Blocks
Check for Block Availability
from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_sva_claims
@sva_oauth_required
def my_view(request):
claims = get_sva_claims(request)
# Check if specific blocks are available
has_pan = 'pan_card' in claims
has_aadhar = 'aadhar' in claims
has_education = 'education' in claims
context = {
'has_pan': has_pan,
'has_aadhar': has_aadhar,
'has_education': has_education,
}
# Add block data if available
if has_pan:
context['pan_card'] = claims['pan_card']
return render(request, 'template.html', context)
Require Custom Blocks
from sva_oauth_client.decorators import sva_blocks_required
@sva_blocks_required('email', 'pan_card', 'aadhar')
def kyc_view(request):
"""KYC verification view requiring PAN and Aadhaar"""
claims = get_sva_claims(request)
# All blocks are guaranteed to exist
return render(request, 'kyc.html', {
'email': claims['email'],
'pan_card': claims['pan_card'],
'aadhar': claims['aadhar'],
})
Complex Block Structures
Address Block
address = claims.get('address')
if address:
street = address.get('street')
city = address.get('city')
state = address.get('state')
zip_code = address.get('zip')
country = address.get('country')
Social Block
social = claims.get('social')
if social:
twitter = social.get('twitter')
github = social.get('github')
linkedin = social.get('linkedin')
Education Block
education = claims.get('education')
if education:
# education is typically a list
for edu in education:
degree = edu.get('degree')
institution = edu.get('institution')
year = edu.get('year')
Employment Block
employment = claims.get('employment')
if employment:
# employment is typically a list
for emp in employment:
company = emp.get('company')
position = emp.get('position')
start_date = emp.get('start_date')
end_date = emp.get('end_date')
Dynamic Scope Selection
Allow users to choose what to share:
def scope_selection_view(request):
"""Let user choose scopes before login"""
if request.method == 'POST':
selected_scopes = request.POST.getlist('scopes')
scopes_string = ' '.join(['openid'] + selected_scopes)
# Store selected scopes in session
request.session['selected_scopes'] = scopes_string
# Redirect to login with custom scopes
return redirect('custom_oauth_login')
return render(request, 'scope_selection.html')
def custom_oauth_login(request):
"""Login with user-selected scopes"""
scopes = request.session.get('selected_scopes', 'openid email profile')
client = SVAOAuthClient(
# ... client config
scopes=scopes,
)
auth_url, code_verifier = client.get_authorization_url()
request.session['code_verifier'] = code_verifier
return redirect(auth_url)
Scope Validation
Validate that required scopes are present:
def validate_scopes(claims, required_scopes):
"""Validate that required scopes are present in claims"""
missing = []
for scope in required_scopes:
if scope not in claims:
missing.append(scope)
return missing
@sva_oauth_required
def my_view(request):
claims = get_sva_claims(request)
required = ['email', 'name', 'phone']
missing = validate_scopes(claims, required)
if missing:
messages.warning(request, f'Missing required data: {", ".join(missing)}')
return redirect('sva_oauth_client:login')
# All required scopes are present
return render(request, 'template.html', {'claims': claims})
Next Steps
- Check Basic Usage for simpler examples
- Explore Advanced Usage for complex scenarios
- See Identity Blocks for complete list