0
# Configuration and Settings
1
2
Comprehensive configuration system for customizing JWT behavior including token expiration, algorithms, secret keys, and handler functions. The settings system provides centralized control over all JWT authentication aspects.
3
4
## Capabilities
5
6
### Settings Access
7
8
Central configuration object providing access to all JWT settings with defaults and validation.
9
10
```python { .api }
11
from rest_framework_jwt.settings import api_settings
12
13
# Access configuration values
14
api_settings.JWT_SECRET_KEY: str
15
api_settings.JWT_ALGORITHM: str
16
api_settings.JWT_EXPIRATION_DELTA: timedelta
17
api_settings.JWT_ALLOW_REFRESH: bool
18
api_settings.JWT_AUTH_HEADER_PREFIX: str
19
# ... and all other JWT settings
20
```
21
22
### Core Settings Structure
23
24
```python { .api }
25
# Module-level configuration objects
26
USER_SETTINGS: Optional[Dict[str, Any]]
27
"""User-defined JWT_AUTH settings from Django settings module."""
28
29
DEFAULTS: Dict[str, Any]
30
"""Default values for all JWT configuration options."""
31
32
IMPORT_STRINGS: Tuple[str, ...]
33
"""Settings that should be imported as functions or classes."""
34
35
api_settings: APISettings
36
"""Main configuration object with merged user settings and defaults."""
37
```
38
39
## Configuration Categories
40
41
### Handler Functions
42
43
Customizable functions that control JWT token processing and validation.
44
45
```python { .api }
46
# Token Processing Handlers
47
JWT_ENCODE_HANDLER: str = 'rest_framework_jwt.utils.jwt_encode_handler'
48
"""Function to encode JWT payloads into token strings."""
49
50
JWT_DECODE_HANDLER: str = 'rest_framework_jwt.utils.jwt_decode_handler'
51
"""Function to decode and validate JWT token strings."""
52
53
JWT_PAYLOAD_HANDLER: str = 'rest_framework_jwt.utils.jwt_payload_handler'
54
"""Function to generate JWT payload from user instance."""
55
56
JWT_PAYLOAD_GET_USERNAME_HANDLER: str = 'rest_framework_jwt.utils.jwt_get_username_from_payload_handler'
57
"""Function to extract username from JWT payload."""
58
59
JWT_PAYLOAD_GET_USER_ID_HANDLER: str = 'rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler'
60
"""Function to extract user ID from JWT payload (deprecated)."""
61
62
JWT_RESPONSE_PAYLOAD_HANDLER: str = 'rest_framework_jwt.utils.jwt_response_payload_handler'
63
"""Function to format JWT response data."""
64
65
JWT_GET_USER_SECRET_KEY: Optional[str] = None
66
"""Function to generate user-specific secret keys."""
67
```
68
69
### Cryptographic Settings
70
71
Security-related configuration for JWT signing and verification.
72
73
```python { .api }
74
JWT_SECRET_KEY: str = settings.SECRET_KEY
75
"""Secret key for HMAC-based JWT signing (default: Django SECRET_KEY)."""
76
77
JWT_PRIVATE_KEY: Optional[str] = None
78
"""Private key for RSA/ECDSA JWT signing."""
79
80
JWT_PUBLIC_KEY: Optional[str] = None
81
"""Public key for RSA/ECDSA JWT verification."""
82
83
JWT_ALGORITHM: str = 'HS256'
84
"""Algorithm for JWT signing and verification."""
85
86
JWT_VERIFY: bool = True
87
"""Whether to verify JWT signatures."""
88
89
JWT_VERIFY_EXPIRATION: bool = True
90
"""Whether to verify JWT expiration times."""
91
92
JWT_LEEWAY: int = 0
93
"""Leeway in seconds for expiration verification."""
94
```
95
96
### Token Lifetime Settings
97
98
Configuration for token expiration and refresh behavior.
99
100
```python { .api }
101
JWT_EXPIRATION_DELTA: timedelta = timedelta(seconds=300)
102
"""Token lifetime (default: 5 minutes)."""
103
104
JWT_ALLOW_REFRESH: bool = False
105
"""Whether to allow token refresh."""
106
107
JWT_REFRESH_EXPIRATION_DELTA: timedelta = timedelta(days=7)
108
"""Maximum time allowed for token refresh."""
109
```
110
111
### Authentication Settings
112
113
Configuration for how tokens are transmitted and processed.
114
115
```python { .api }
116
JWT_AUTH_HEADER_PREFIX: str = 'JWT'
117
"""Prefix for Authorization header (e.g., 'Authorization: JWT <token>')."""
118
119
JWT_AUTH_COOKIE: Optional[str] = None
120
"""Cookie name for JWT storage (enables cookie-based authentication)."""
121
```
122
123
### Claims Settings
124
125
Optional JWT standard claims for enhanced security.
126
127
```python { .api }
128
JWT_AUDIENCE: Optional[str] = None
129
"""JWT audience claim for token validation."""
130
131
JWT_ISSUER: Optional[str] = None
132
"""JWT issuer claim for token validation."""
133
```
134
135
## Usage Examples
136
137
### Basic Configuration
138
139
```python
140
# In Django settings.py
141
JWT_AUTH = {
142
'JWT_SECRET_KEY': 'your-secret-key-here',
143
'JWT_ALGORITHM': 'HS256',
144
'JWT_EXPIRATION_DELTA': timedelta(hours=1),
145
'JWT_ALLOW_REFRESH': True,
146
'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=7),
147
'JWT_AUTH_HEADER_PREFIX': 'Bearer', # Change from 'JWT' to 'Bearer'
148
}
149
```
150
151
### Production Security Configuration
152
153
```python
154
import datetime
155
156
JWT_AUTH = {
157
# Use environment variable for secret key
158
'JWT_SECRET_KEY': os.environ.get('JWT_SECRET_KEY', settings.SECRET_KEY),
159
160
# Strong algorithm
161
'JWT_ALGORITHM': 'HS256',
162
163
# Reasonable token lifetime
164
'JWT_EXPIRATION_DELTA': datetime.timedelta(minutes=15),
165
166
# Enable refresh with limited window
167
'JWT_ALLOW_REFRESH': True,
168
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(hours=24),
169
170
# Enable verification
171
'JWT_VERIFY': True,
172
'JWT_VERIFY_EXPIRATION': True,
173
'JWT_LEEWAY': 10, # 10 seconds leeway for clock skew
174
175
# Add audience and issuer claims
176
'JWT_AUDIENCE': 'myapp-api',
177
'JWT_ISSUER': 'myapp.com',
178
179
# Use cookie for web clients
180
'JWT_AUTH_COOKIE': 'jwt-token',
181
}
182
```
183
184
### Custom Handler Functions
185
186
```python
187
# Custom payload handler
188
def custom_jwt_payload_handler(user):
189
return {
190
'user_id': user.id,
191
'username': user.username,
192
'email': user.email,
193
'is_staff': user.is_staff,
194
'groups': [group.name for group in user.groups.all()],
195
'exp': datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA,
196
'iat': datetime.utcnow(),
197
}
198
199
# Custom response handler
200
def custom_jwt_response_handler(token, user=None, request=None):
201
return {
202
'token': token,
203
'user': {
204
'id': user.id,
205
'username': user.username,
206
'email': user.email,
207
'full_name': user.get_full_name(),
208
},
209
'expires': (datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA).isoformat(),
210
}
211
212
# User-specific secret key for token invalidation
213
def get_user_secret_key(user):
214
# Tokens become invalid when user password changes
215
return f"{settings.SECRET_KEY}:{user.password[:10]}"
216
217
# Configuration
218
JWT_AUTH = {
219
'JWT_PAYLOAD_HANDLER': 'myapp.utils.custom_jwt_payload_handler',
220
'JWT_RESPONSE_PAYLOAD_HANDLER': 'myapp.utils.custom_jwt_response_handler',
221
'JWT_GET_USER_SECRET_KEY': 'myapp.utils.get_user_secret_key',
222
}
223
```
224
225
### RSA Key Configuration
226
227
```python
228
# For RSA-based signing (more secure but requires key management)
229
JWT_AUTH = {
230
'JWT_ALGORITHM': 'RS256',
231
'JWT_PRIVATE_KEY': '''-----BEGIN RSA PRIVATE KEY-----
232
MIIEpAIBAAKCAQEA...
233
-----END RSA PRIVATE KEY-----''',
234
'JWT_PUBLIC_KEY': '''-----BEGIN PUBLIC KEY-----
235
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
236
-----END PUBLIC KEY-----''',
237
}
238
```
239
240
### Environment-Based Configuration
241
242
```python
243
import os
244
from datetime import timedelta
245
246
# Load from environment variables for different deployment environments
247
JWT_AUTH = {
248
'JWT_SECRET_KEY': os.getenv('JWT_SECRET_KEY', settings.SECRET_KEY),
249
'JWT_ALGORITHM': os.getenv('JWT_ALGORITHM', 'HS256'),
250
'JWT_EXPIRATION_DELTA': timedelta(
251
seconds=int(os.getenv('JWT_EXPIRATION_SECONDS', '900')) # 15 min default
252
),
253
'JWT_ALLOW_REFRESH': os.getenv('JWT_ALLOW_REFRESH', 'false').lower() == 'true',
254
'JWT_REFRESH_EXPIRATION_DELTA': timedelta(
255
hours=int(os.getenv('JWT_REFRESH_HOURS', '24'))
256
),
257
'JWT_AUTH_HEADER_PREFIX': os.getenv('JWT_AUTH_HEADER_PREFIX', 'JWT'),
258
'JWT_AUTH_COOKIE': os.getenv('JWT_AUTH_COOKIE'), # None if not set
259
'JWT_AUDIENCE': os.getenv('JWT_AUDIENCE'),
260
'JWT_ISSUER': os.getenv('JWT_ISSUER'),
261
}
262
```
263
264
## Settings Access in Code
265
266
### Reading Configuration Values
267
268
```python
269
from rest_framework_jwt.settings import api_settings
270
271
# Access individual settings
272
secret_key = api_settings.JWT_SECRET_KEY
273
algorithm = api_settings.JWT_ALGORITHM
274
expiration = api_settings.JWT_EXPIRATION_DELTA
275
276
# Check if refresh is enabled
277
if api_settings.JWT_ALLOW_REFRESH:
278
# Handle refresh logic
279
pass
280
281
# Get handler functions
282
payload_handler = api_settings.JWT_PAYLOAD_HANDLER
283
encode_handler = api_settings.JWT_ENCODE_HANDLER
284
```
285
286
### Dynamic Configuration
287
288
```python
289
# Settings can be modified at runtime (not recommended for production)
290
from rest_framework_jwt.settings import api_settings
291
from django.test import override_settings
292
293
# In tests
294
with override_settings(JWT_AUTH={'JWT_EXPIRATION_DELTA': timedelta(seconds=1)}):
295
# Test with very short token lifetime
296
pass
297
```
298
299
## Validation and Error Handling
300
301
### Invalid Handler Functions
302
303
```python
304
# If a handler function path is invalid
305
JWT_AUTH = {
306
'JWT_PAYLOAD_HANDLER': 'nonexistent.module.function',
307
}
308
309
# Results in ImportError when api_settings is accessed
310
try:
311
from rest_framework_jwt.settings import api_settings
312
handler = api_settings.JWT_PAYLOAD_HANDLER
313
except ImportError as e:
314
print(f"Invalid handler configuration: {e}")
315
```
316
317
### Required vs Optional Settings
318
319
```python
320
# Required (have defaults)
321
- JWT_SECRET_KEY (defaults to Django SECRET_KEY)
322
- JWT_ALGORITHM (defaults to 'HS256')
323
- JWT_EXPIRATION_DELTA (defaults to 5 minutes)
324
325
# Optional (None by default)
326
- JWT_PRIVATE_KEY
327
- JWT_PUBLIC_KEY
328
- JWT_AUTH_COOKIE
329
- JWT_AUDIENCE
330
- JWT_ISSUER
331
- JWT_GET_USER_SECRET_KEY
332
```
333
334
## Security Best Practices
335
336
### Key Management
337
338
```python
339
# DO: Use environment variables for secrets
340
JWT_AUTH = {
341
'JWT_SECRET_KEY': os.environ['JWT_SECRET_KEY'],
342
}
343
344
# DON'T: Hard-code secrets in settings files
345
JWT_AUTH = {
346
'JWT_SECRET_KEY': 'hardcoded-secret-key', # Never do this
347
}
348
```
349
350
### Token Lifetime
351
352
```python
353
# Balance security vs usability
354
JWT_AUTH = {
355
# Short-lived access tokens
356
'JWT_EXPIRATION_DELTA': timedelta(minutes=15),
357
358
# Reasonable refresh window
359
'JWT_ALLOW_REFRESH': True,
360
'JWT_REFRESH_EXPIRATION_DELTA': timedelta(hours=24),
361
}
362
```
363
364
### Algorithm Selection
365
366
```python
367
# Recommended algorithms by use case:
368
369
# High security (requires key management)
370
'JWT_ALGORITHM': 'RS256' # RSA with SHA-256
371
372
# Balanced (simpler key management)
373
'JWT_ALGORITHM': 'HS256' # HMAC with SHA-256
374
375
# Avoid weak algorithms
376
'JWT_ALGORITHM': 'none' # Never use this
377
'JWT_ALGORITHM': 'HS1' # Deprecated/weak
378
```
379
380
The configuration system provides extensive flexibility while maintaining secure defaults for JWT authentication behavior.