0
# JWT Utilities
1
2
Essential functions for JWT token creation, validation, and payload management. These utilities handle the core JWT operations including encoding, decoding, payload generation, and secret key management.
3
4
## Capabilities
5
6
### Token Encoding and Decoding
7
8
Core functions for JWT token creation and validation.
9
10
```python { .api }
11
def jwt_encode_handler(payload):
12
"""
13
Encodes a payload dictionary into a JWT token string.
14
15
Args:
16
payload (dict): JWT payload containing claims and user data
17
18
Returns:
19
str: Encoded JWT token
20
21
Note:
22
Uses configured algorithm, secret key, and signing options from settings.
23
"""
24
25
def jwt_decode_handler(token):
26
"""
27
Decodes and validates a JWT token string.
28
29
Args:
30
token (str): JWT token string to decode
31
32
Returns:
33
dict: Decoded payload containing claims and user data
34
35
Raises:
36
jwt.ExpiredSignature: Token has expired
37
jwt.DecodeError: Token is malformed or invalid
38
jwt.InvalidTokenError: Token signature is invalid
39
40
Note:
41
Validates expiration, signature, audience, and issuer based on settings.
42
"""
43
```
44
45
### Payload Management
46
47
Functions for creating and processing JWT payloads with user information.
48
49
```python { .api }
50
def jwt_payload_handler(user):
51
"""
52
Creates a JWT payload from a Django user instance.
53
54
Args:
55
user: Django user model instance
56
57
Returns:
58
dict: JWT payload containing user claims and metadata
59
60
Payload Structure:
61
- user_id: User primary key (deprecated, use username field)
62
- username: User's username
63
- exp: Expiration timestamp
64
- email: User's email (if available, deprecated)
65
- orig_iat: Original issued-at time (if refresh enabled)
66
- aud: Audience claim (if configured)
67
- iss: Issuer claim (if configured)
68
- {username_field}: Username value using configured field name
69
70
Deprecation Warnings:
71
Issues warnings about future removal of 'email' and 'user_id' fields.
72
These fields will be removed in future versions.
73
74
Special Handling:
75
- UUID primary keys are converted to strings
76
- Username field is dynamically determined from User model
77
- Expiration calculated from JWT_EXPIRATION_DELTA setting
78
"""
79
80
def jwt_get_username_from_payload_handler(payload):
81
"""
82
Extracts username from JWT payload.
83
84
Args:
85
payload (dict): Decoded JWT payload
86
87
Returns:
88
str: Username from payload
89
"""
90
91
def jwt_get_user_id_from_payload_handler(payload):
92
"""
93
Extracts user ID from JWT payload (deprecated).
94
95
Args:
96
payload (dict): Decoded JWT payload
97
98
Returns:
99
Any: User ID from payload
100
101
Deprecated:
102
This function is deprecated and will be removed in future versions.
103
Use JWT_PAYLOAD_GET_USERNAME_HANDLER instead. Issues deprecation
104
warning when called.
105
"""
106
```
107
108
### Secret Key Management
109
110
Functions for managing JWT signing keys, including user-specific secret keys.
111
112
```python { .api }
113
def jwt_get_secret_key(payload=None):
114
"""
115
Retrieves the secret key for JWT signing/verification.
116
117
Args:
118
payload (dict, optional): JWT payload for user-specific keys
119
120
Returns:
121
str: Secret key for JWT operations
122
123
Note:
124
- Returns user-specific key if JWT_GET_USER_SECRET_KEY is configured
125
- Falls back to JWT_SECRET_KEY setting
126
- Enables per-user token invalidation for enhanced security
127
"""
128
```
129
130
### Response Handling
131
132
Function for customizing JWT response payloads.
133
134
```python { .api }
135
def jwt_response_payload_handler(token, user=None, request=None):
136
"""
137
Formats the response payload for JWT authentication endpoints.
138
139
Args:
140
token (str): Generated JWT token
141
user (User, optional): Authenticated user instance
142
request (HttpRequest, optional): Current request object
143
144
Returns:
145
dict: Response data sent to client
146
147
Default Response:
148
{'token': token}
149
150
Customization Example:
151
return {
152
'token': token,
153
'user': UserSerializer(user).data,
154
'expires': payload['exp']
155
}
156
"""
157
```
158
159
## Usage Examples
160
161
### Custom Payload Handler
162
163
```python
164
from rest_framework_jwt.utils import jwt_payload_handler
165
from datetime import datetime, timedelta
166
167
def custom_jwt_payload_handler(user):
168
"""Add custom claims to JWT payload."""
169
payload = jwt_payload_handler(user)
170
171
# Add custom claims
172
payload.update({
173
'role': user.role,
174
'permissions': list(user.permissions.values_list('name', flat=True)),
175
'organization': user.organization.id if user.organization else None,
176
})
177
178
return payload
179
180
# Configure in settings
181
JWT_AUTH = {
182
'JWT_PAYLOAD_HANDLER': 'myapp.utils.custom_jwt_payload_handler',
183
}
184
```
185
186
### Custom Response Handler
187
188
```python
189
def custom_jwt_response_handler(token, user=None, request=None):
190
"""Include user data in JWT response."""
191
return {
192
'token': token,
193
'user': {
194
'id': user.id,
195
'username': user.username,
196
'email': user.email,
197
'full_name': user.get_full_name(),
198
},
199
'expires_in': 300, # Token lifetime in seconds
200
}
201
202
# Configure in settings
203
JWT_AUTH = {
204
'JWT_RESPONSE_PAYLOAD_HANDLER': 'myapp.utils.custom_jwt_response_handler',
205
}
206
```
207
208
### User-Specific Secret Keys
209
210
```python
211
def get_user_secret_key(user):
212
"""Generate user-specific secret key for token invalidation."""
213
# Use user's password hash as part of secret
214
# Tokens become invalid when password changes
215
return f"{settings.SECRET_KEY}:{user.password}"
216
217
# Configure in settings
218
JWT_AUTH = {
219
'JWT_GET_USER_SECRET_KEY': 'myapp.utils.get_user_secret_key',
220
}
221
```
222
223
### Manual Token Operations
224
225
```python
226
from rest_framework_jwt.utils import (
227
jwt_payload_handler, jwt_encode_handler, jwt_decode_handler
228
)
229
from django.contrib.auth import get_user_model
230
231
User = get_user_model()
232
233
# Create token manually
234
user = User.objects.get(username='testuser')
235
payload = jwt_payload_handler(user)
236
token = jwt_encode_handler(payload)
237
238
# Validate token manually
239
try:
240
decoded_payload = jwt_decode_handler(token)
241
username = decoded_payload['username']
242
print(f"Token valid for user: {username}")
243
except Exception as e:
244
print(f"Token validation failed: {e}")
245
```
246
247
## Configuration Integration
248
249
These utilities are configured through the `JWT_AUTH` settings dictionary:
250
251
```python
252
JWT_AUTH = {
253
# Handler Functions
254
'JWT_PAYLOAD_HANDLER': 'rest_framework_jwt.utils.jwt_payload_handler',
255
'JWT_ENCODE_HANDLER': 'rest_framework_jwt.utils.jwt_encode_handler',
256
'JWT_DECODE_HANDLER': 'rest_framework_jwt.utils.jwt_decode_handler',
257
'JWT_RESPONSE_PAYLOAD_HANDLER': 'rest_framework_jwt.utils.jwt_response_payload_handler',
258
259
# Secret Key Options
260
'JWT_SECRET_KEY': settings.SECRET_KEY,
261
'JWT_GET_USER_SECRET_KEY': None, # For user-specific keys
262
263
# Token Settings
264
'JWT_ALGORITHM': 'HS256',
265
'JWT_EXPIRATION_DELTA': timedelta(seconds=300),
266
'JWT_ALLOW_REFRESH': False,
267
268
# Verification Options
269
'JWT_VERIFY': True,
270
'JWT_VERIFY_EXPIRATION': True,
271
'JWT_LEEWAY': 0,
272
273
# Claims
274
'JWT_AUDIENCE': None,
275
'JWT_ISSUER': None,
276
}
277
```
278
279
## Error Handling
280
281
The utility functions handle various JWT-related errors:
282
283
```python
284
import jwt
285
from rest_framework.exceptions import AuthenticationFailed
286
287
# Common errors from jwt_decode_handler:
288
try:
289
payload = jwt_decode_handler(token)
290
except jwt.ExpiredSignature:
291
# Token has expired
292
pass
293
except jwt.DecodeError:
294
# Token is malformed
295
pass
296
except jwt.InvalidTokenError:
297
# Invalid signature or claims
298
pass
299
```
300
301
These errors are typically caught by authentication classes and converted to appropriate HTTP responses.