0
# Views and Endpoints
1
2
Ready-to-use API views for JWT token operations including token generation, verification, and refresh functionality. These views provide complete HTTP endpoints for JWT authentication workflows.
3
4
## Capabilities
5
6
### Base JWT API View
7
8
Foundation class for all JWT-related API views with common functionality.
9
10
```python { .api }
11
class JSONWebTokenAPIView(APIView):
12
permission_classes = ()
13
authentication_classes = ()
14
15
def get_serializer_context(self):
16
"""
17
Returns extra context for serializer.
18
19
Returns:
20
dict: Context containing request and view instances
21
"""
22
23
def get_serializer_class(self):
24
"""
25
Returns the serializer class for this view.
26
27
Returns:
28
class: Serializer class to use for validation
29
30
Raises:
31
AssertionError: If serializer_class is not defined
32
"""
33
34
def get_serializer(self, *args, **kwargs):
35
"""
36
Returns serializer instance for validation and processing.
37
38
Args:
39
*args: Positional arguments for serializer
40
**kwargs: Keyword arguments for serializer
41
42
Returns:
43
Serializer: Configured serializer instance
44
"""
45
46
def post(self, request, *args, **kwargs):
47
"""
48
Handles POST requests for JWT operations.
49
50
Args:
51
request: HTTP request object
52
*args: Additional positional arguments
53
**kwargs: Additional keyword arguments
54
55
Returns:
56
Response: JSON response with token data or validation errors
57
58
Response Format:
59
Success: {'token': '<jwt_token>', ...custom_data}
60
Error: {field_name: [error_messages]}
61
"""
62
```
63
64
### Token Obtainment View
65
66
API view for obtaining JWT tokens through username/password authentication.
67
68
```python { .api }
69
class ObtainJSONWebToken(JSONWebTokenAPIView):
70
serializer_class = JSONWebTokenSerializer
71
72
# Inherits post() method that:
73
# 1. Validates username/password via serializer
74
# 2. Authenticates user and generates JWT
75
# 3. Returns token response with optional cookie setting
76
```
77
78
### Token Verification View
79
80
API view for verifying the validity of existing JWT tokens.
81
82
```python { .api }
83
class VerifyJSONWebToken(JSONWebTokenAPIView):
84
serializer_class = VerifyJSONWebTokenSerializer
85
86
# Inherits post() method that:
87
# 1. Validates provided token via serializer
88
# 2. Verifies token signature and expiration
89
# 3. Returns token and user information if valid
90
```
91
92
### Token Refresh View
93
94
API view for refreshing JWT tokens to extend their lifetime.
95
96
```python { .api }
97
class RefreshJSONWebToken(JSONWebTokenAPIView):
98
serializer_class = RefreshJSONWebTokenSerializer
99
100
# Inherits post() method that:
101
# 1. Validates existing token via serializer
102
# 2. Checks refresh eligibility and expiration
103
# 3. Generates new token with extended expiration
104
```
105
106
### Function-Based Views
107
108
Pre-configured view instances ready for URL routing.
109
110
```python { .api }
111
obtain_jwt_token = ObtainJSONWebToken.as_view()
112
"""
113
Function-based view for obtaining JWT tokens.
114
115
POST /api-token-auth/
116
{
117
"username": "user@example.com",
118
"password": "password123"
119
}
120
121
Response:
122
{
123
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
124
}
125
"""
126
127
refresh_jwt_token = RefreshJSONWebToken.as_view()
128
"""
129
Function-based view for refreshing JWT tokens.
130
131
POST /api-token-refresh/
132
{
133
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
134
}
135
136
Response:
137
{
138
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
139
}
140
"""
141
142
verify_jwt_token = VerifyJSONWebToken.as_view()
143
"""
144
Function-based view for verifying JWT tokens.
145
146
POST /api-token-verify/
147
{
148
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
149
}
150
151
Response:
152
{
153
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
154
}
155
"""
156
```
157
158
## Usage Examples
159
160
### URL Configuration
161
162
```python
163
# urls.py
164
from django.urls import path
165
from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token, verify_jwt_token
166
167
urlpatterns = [
168
path('api-token-auth/', obtain_jwt_token),
169
path('api-token-refresh/', refresh_jwt_token),
170
path('api-token-verify/', verify_jwt_token),
171
]
172
```
173
174
### Custom JWT Views
175
176
```python
177
from rest_framework_jwt.views import JSONWebTokenAPIView
178
from rest_framework_jwt.serializers import JSONWebTokenSerializer
179
from rest_framework.response import Response
180
from django.contrib.auth import authenticate
181
182
class CustomObtainJWT(JSONWebTokenAPIView):
183
serializer_class = JSONWebTokenSerializer
184
185
def post(self, request, *args, **kwargs):
186
# Add custom logic before token generation
187
serializer = self.get_serializer(data=request.data)
188
189
if serializer.is_valid():
190
# Custom authentication logging
191
user = serializer.object.get('user')
192
self.log_authentication(user, request)
193
194
# Generate response with additional data
195
token = serializer.object.get('token')
196
response_data = {
197
'token': token,
198
'user': {
199
'id': user.id,
200
'username': user.username,
201
'last_login': user.last_login.isoformat() if user.last_login else None,
202
},
203
'expires_in': 300,
204
}
205
206
return Response(response_data)
207
208
return Response(serializer.errors, status=400)
209
210
def log_authentication(self, user, request):
211
# Custom logging logic
212
pass
213
```
214
215
### API Endpoint Testing
216
217
```python
218
import requests
219
220
# Test token obtainment
221
response = requests.post('http://localhost:8000/api-token-auth/', {
222
'username': 'testuser',
223
'password': 'testpass123'
224
})
225
226
if response.status_code == 200:
227
token = response.json()['token']
228
print(f"Token obtained: {token}")
229
230
# Test token verification
231
verify_response = requests.post('http://localhost:8000/api-token-verify/', {
232
'token': token
233
})
234
235
if verify_response.status_code == 200:
236
print("Token is valid")
237
else:
238
print("Token verification failed")
239
240
# Test authenticated request
241
headers = {'Authorization': f'JWT {token}'}
242
api_response = requests.get(
243
'http://localhost:8000/api/protected-endpoint/',
244
headers=headers
245
)
246
247
print(f"API Response: {api_response.status_code}")
248
else:
249
print(f"Authentication failed: {response.json()}")
250
```
251
252
### AJAX Integration
253
254
```javascript
255
// JavaScript client-side usage
256
async function authenticateUser(credentials) {
257
try {
258
const response = await fetch('/api-token-auth/', {
259
method: 'POST',
260
headers: {
261
'Content-Type': 'application/json',
262
'X-CSRFToken': getCsrfToken(),
263
},
264
body: JSON.stringify(credentials)
265
});
266
267
if (response.ok) {
268
const data = await response.json();
269
localStorage.setItem('jwt_token', data.token);
270
return data.token;
271
} else {
272
const errors = await response.json();
273
throw new Error(`Authentication failed: ${JSON.stringify(errors)}`);
274
}
275
} catch (error) {
276
console.error('Authentication error:', error);
277
throw error;
278
}
279
}
280
281
async function makeAuthenticatedRequest(url, options = {}) {
282
const token = localStorage.getItem('jwt_token');
283
284
if (!token) {
285
throw new Error('No authentication token available');
286
}
287
288
const headers = {
289
'Authorization': `JWT ${token}`,
290
'Content-Type': 'application/json',
291
...options.headers,
292
};
293
294
return fetch(url, {
295
...options,
296
headers,
297
});
298
}
299
```
300
301
## Response Formats
302
303
### Successful Token Obtainment
304
305
```json
306
{
307
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6InRlc3R1c2VyIiwiZXhwIjoxNjIzNzUwNDAwfQ.signature"
308
}
309
```
310
311
### Authentication Errors
312
313
```json
314
{
315
"non_field_errors": ["Unable to log in with provided credentials."]
316
}
317
```
318
319
### Validation Errors
320
321
```json
322
{
323
"username": ["This field is required."],
324
"password": ["This field is required."]
325
}
326
```
327
328
### Token Verification Success
329
330
```json
331
{
332
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
333
}
334
```
335
336
### Token Errors
337
338
```json
339
{
340
"non_field_errors": ["Signature has expired."]
341
}
342
```
343
344
## Cookie Support
345
346
Views automatically handle JWT cookie storage when configured:
347
348
```python
349
# In settings.py
350
JWT_AUTH = {
351
'JWT_AUTH_COOKIE': 'jwt-token',
352
'JWT_EXPIRATION_DELTA': timedelta(hours=1),
353
}
354
```
355
356
When `JWT_AUTH_COOKIE` is set, successful token obtainment will:
357
1. Return token in JSON response
358
2. Set HTTP-only cookie with token value
359
3. Configure cookie expiration to match token expiration
360
361
## Error Handling
362
363
The views handle various error conditions:
364
365
- **400 Bad Request**: Invalid input data or validation errors
366
- **401 Unauthorized**: Invalid credentials or expired tokens
367
- **500 Internal Server Error**: Server-side configuration or processing errors
368
369
Error responses include descriptive messages to help clients handle authentication failures appropriately.
370
371
## Module Variables
372
373
The views module defines handler function references used by the API views:
374
375
```python { .api }
376
jwt_response_payload_handler = api_settings.JWT_RESPONSE_PAYLOAD_HANDLER
377
"""Function reference for formatting JWT response payloads."""
378
```
379
380
## Security Considerations
381
382
The JWT views implement several security best practices:
383
384
- **No authentication required**: Views are publicly accessible for token operations
385
- **HTTPS recommended**: Tokens should be transmitted over secure connections
386
- **Cookie security**: HTTP-only cookies prevent XSS attacks
387
- **Token expiration**: Configurable token lifetimes limit exposure window
388
- **Input validation**: Comprehensive validation prevents injection attacks