A professional Django package for integrating SVA (Secure Vault Authentication) OAuth provider into your Django applications. This package provides a complete solution for authenticating users via SVA OAuth and retrieving identity blocks data from the consent screen.
- âś… Complete OAuth 2.0 Flow: Authorization Code Flow with PKCE support
- âś… Simplified API: New easy-to-use facade that reduces boilerplate code
- âś… Easy Integration: Simple decorators and utilities for quick setup
- âś… Identity Blocks: Retrieve all blocks data from consent screen
- âś… Session Management: Automatic token storage and management
- âś… Error Handling: Comprehensive error handling with user-friendly messages
- âś… Django Integration: Seamless integration with Django views and templates
- âś… Type Hints: Full type hint support for better IDE experience
- âś… Backward Compatible: All existing code continues to work
pip install sva-oauth-clientOr install from source:
git clone https://github.com/getsva/sva-oauth-client.git
cd sva-oauth-client
pip install -e .# settings.py
INSTALLED_APPS = [
# ... other apps
'sva_oauth_client',
]# settings.py
# SVA OAuth Configuration
SVA_OAUTH_BASE_URL = 'http://localhost:8000' # Your SVA OAuth provider URL
SVA_OAUTH_CLIENT_ID = 'your_client_id_here'
SVA_OAUTH_CLIENT_SECRET = 'your_client_secret_here'
SVA_OAUTH_REDIRECT_URI = 'http://localhost:8001/oauth/callback/'
SVA_DATA_TOKEN_SECRET = 'your_data_token_secret' # Must match SVA provider
SVA_DATA_TOKEN_ALGORITHM = 'HS256' # Default: HS256
# Optional: Request specific scopes (default: 'openid email profile')
SVA_OAUTH_SCOPES = 'openid email profile username name bio address social images pronoun dob skills hobby email phone pan_card crypto_wallet education employment professional_license aadhar driving_license voter_id passport'
# Optional: Custom redirect URLs
SVA_OAUTH_SUCCESS_REDIRECT = '/' # After successful login
SVA_OAUTH_ERROR_REDIRECT = '/' # On error
SVA_OAUTH_LOGOUT_REDIRECT = '/' # After logout
SVA_OAUTH_LOGIN_URL = '/oauth/login/' # Login URL# urls.py
from django.urls import path, include
urlpatterns = [
# ... other URLs
path('oauth/', include('sva_oauth_client.urls')),
]The new simplified API makes it much easier to work with SVA OAuth:
from sva_oauth_client import get_sva
from sva_oauth_client.decorators import sva_oauth_required
@sva_oauth_required
def my_view(request):
sva = get_sva(request)
# Get all blocks
blocks = sva.get_blocks()
# Get specific blocks easily
email = sva.get_block('email')
name = sva.get_block('name')
# Check if block exists
has_phone = sva.has_block('phone')
# Get userinfo
userinfo = sva.get_userinfo()
return render(request, 'my_template.html', {
'blocks': blocks,
'email': email,
'name': name,
'userinfo': userinfo,
})from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_blocks_data, get_userinfo
@sva_oauth_required
def my_view(request):
# User is authenticated with SVA OAuth
blocks_data = get_blocks_data(request.session)
userinfo = get_userinfo(request.session)
return render(request, 'my_template.html', {
'blocks': blocks_data,
'userinfo': userinfo,
})Simplified API:
from sva_oauth_client import get_sva
from sva_oauth_client.decorators import sva_blocks_required
@sva_blocks_required('email', 'name', 'phone')
def my_view(request):
sva = get_sva(request)
# Blocks are guaranteed to be available
email = sva.get_block('email')
name = sva.get_block('name')
phone = sva.get_block('phone')
return render(request, 'my_template.html', {
'email': email,
'name': name,
'phone': phone,
})Traditional API:
from sva_oauth_client.decorators import sva_blocks_required
from sva_oauth_client.utils import get_blocks_data
@sva_blocks_required('email', 'name', 'phone')
def my_view(request):
# User has approved email, name, and phone blocks
blocks_data = get_blocks_data(request.session)
email = blocks_data.get('email')
name = blocks_data.get('name')
phone = blocks_data.get('phone')
return render(request, 'my_template.html', {
'email': email,
'name': name,
'phone': phone,
})from sva_oauth_client import SVAOAuthClient
# Initialize client
client = SVAOAuthClient(
base_url='http://localhost:8000',
client_id='your_client_id',
client_secret='your_client_secret',
redirect_uri='http://localhost:8001/oauth/callback/',
data_token_secret='your_data_token_secret',
)
# Get authorization URL
auth_url, code_verifier = client.get_authorization_url()
# Store code_verifier in session
request.session['code_verifier'] = code_verifier
# Redirect user to auth_url
# After callback, exchange code for tokens
tokens = client.exchange_code_for_tokens(
code=request.GET.get('code'),
code_verifier=request.session.get('code_verifier')
)
# Get blocks data
blocks_data = client.get_blocks_data(tokens['data_token'])Get SVA facade instance for easy access to all OAuth functionality.
from sva_oauth_client import get_sva
def my_view(request):
sva = get_sva(request)
# Check authentication
if sva.is_authenticated():
# Get all blocks
blocks = sva.get_blocks()
# Get specific block
email = sva.get_block('email')
# Check if block exists
has_phone = sva.has_block('phone')
# Get userinfo
userinfo = sva.get_userinfo()
# Force refresh userinfo
fresh_userinfo = sva.refresh_userinfo()
# Logout
sva.logout()is_authenticated() -> bool: Check if user is authenticatedget_blocks() -> dict | None: Get all identity blocks (claims)get_claims() -> dict | None: Alias forget_blocks()get_block(name: str, default: Any = None) -> Any: Get specific block valuehas_block(name: str) -> bool: Check if block existsget_userinfo(force_refresh: bool = False) -> dict | None: Get user informationrefresh_userinfo() -> dict | None: Force refresh userinfo from providerget_access_token() -> str | None: Get access tokenget_data_token() -> str | None: Get data tokenlogout() -> None: Clear OAuth sessionget_client() -> SVAOAuthClient: Get underlying OAuth client
Main OAuth client class.
-
get_authorization_url(state=None, code_verifier=None) -> tuple[str, str]- Generate authorization URL and code verifier
- Returns: (authorization_url, code_verifier)
-
exchange_code_for_tokens(code, code_verifier, state=None) -> dict- Exchange authorization code for tokens
- Returns: Dictionary with access_token, refresh_token, data_token, etc.
-
refresh_access_token(refresh_token) -> dict- Refresh access token using refresh token
-
get_userinfo(access_token) -> dict- Get user information from OAuth provider
-
decode_data_token(data_token) -> dict- Decode and verify data_token JWT
-
get_blocks_data(data_token) -> dict- Extract blocks data from data_token
Require SVA OAuth authentication. Redirects to login if not authenticated.
@sva_oauth_required
def my_view(request):
# User is authenticated
passRequire specific identity blocks. Redirects to login if blocks are missing.
@sva_blocks_required('email', 'name', 'phone')
def my_view(request):
# User has approved email, name, and phone
passCentralized configuration manager with validation.
from sva_oauth_client import SVAConfig
# Get configuration values
base_url = SVAConfig.get_base_url()
client_id = SVAConfig.get_client_id()
# Validate configuration
is_valid, missing = SVAConfig.validate()
if not is_valid:
print(f"Missing settings: {missing}")Get blocks data from session.
Get userinfo from session or fetch from OAuth provider.
Get access token from session.
Get data token from session.
Check if user is authenticated with SVA OAuth.
Clear all OAuth-related data from session.
Get claims from request (requires HttpRequest, not just session).
The package supports all SVA identity blocks:
username- Usernamename- Full namebio- Bio/descriptionpronoun- Pronounsdob- Date of birth
images- Profile imagesskills- Skillshobby- Hobbies
address- Addresssocial- Social links
email- Verified emailphone- Verified phonepan_card- PAN cardcrypto_wallet- Crypto walleteducation- Educationemployment- Employmentprofessional_license- Professional licenseaadhar- Aadhaar carddriving_license- Driving licensevoter_id- Voter IDpassport- Passport
# views.py
from django.shortcuts import render
from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_blocks_data, get_userinfo
@sva_oauth_required
def dashboard(request):
blocks_data = get_blocks_data(request.session)
userinfo = get_userinfo(request.session)
context = {
'blocks': blocks_data,
'userinfo': userinfo,
'email': blocks_data.get('email') if blocks_data else None,
'name': blocks_data.get('name') if blocks_data else None,
}
return render(request, 'dashboard.html', context)<!-- dashboard.html -->
<h1>Welcome!</h1>
{% if blocks %}
<h2>Your Identity Blocks</h2>
<ul>
{% for key, value in blocks.items %}
<li><strong>{{ key }}:</strong> {{ value }}</li>
{% endfor %}
</ul>
{% endif %}
{% if userinfo %}
<h2>User Information</h2>
<p>Subject: {{ userinfo.sub }}</p>
<p>Email: {{ userinfo.email }}</p>
{% endif %}The package provides comprehensive error handling:
from sva_oauth_client.client import SVAOAuthClient, SVATokenError, SVAAuthorizationError
try:
client = SVAOAuthClient(...)
tokens = client.exchange_code_for_tokens(code, code_verifier)
except SVATokenError as e:
# Handle token errors
print(f"Token error: {e}")
except SVAAuthorizationError as e:
# Handle authorization errors
print(f"Authorization error: {e}")- Never expose secrets: Keep
SVA_OAUTH_CLIENT_SECRETandSVA_DATA_TOKEN_SECRETsecure - Use HTTPS in production: Always use HTTPS for OAuth redirects in production
- Validate state parameter: The package automatically validates state for CSRF protection
- Store tokens securely: Tokens are stored in Django session (server-side)
- Handle token expiration: Implement token refresh logic for long-lived sessions
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details.
For issues and questions:
- GitHub Issues: https://github.com/getsva/sva-oauth-client/issues
- Email: support@getsva.com