or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcompatibility.mdconfiguration.mdindex.mdjwt-utilities.mdserializers.mdviews-endpoints.md

serializers.mddocs/

0

# Serializers

1

2

Validation and processing classes for JWT authentication workflows, handling user credentials, token verification, and refresh operations. These serializers integrate with Django REST Framework's validation system to process JWT authentication requests.

3

4

## Capabilities

5

6

### JWT Authentication Serializer

7

8

Validates username/password credentials and generates JWT tokens for successful authentication.

9

10

```python { .api }

11

class JSONWebTokenSerializer(Serializer):

12

# Dynamic fields based on user model

13

# username_field: CharField (dynamically added based on User.USERNAME_FIELD)

14

# password: PasswordField (write-only)

15

16

def __init__(self, *args, **kwargs):

17

"""

18

Dynamically adds username field based on User model configuration.

19

20

Adds:

21

- Username field (name from User.USERNAME_FIELD)

22

- Password field (write-only with password input type)

23

"""

24

25

@property

26

def username_field(self):

27

"""

28

Returns the username field name from the User model.

29

30

Returns:

31

str: Field name used for username (e.g., 'username', 'email')

32

"""

33

34

def validate(self, attrs):

35

"""

36

Validates credentials and returns token with user data.

37

38

Args:

39

attrs (dict): Input data containing username and password

40

41

Returns:

42

dict: Contains 'token' (JWT string) and 'user' (User instance)

43

44

Raises:

45

ValidationError: For invalid credentials, inactive users, or missing fields

46

47

Validation Process:

48

1. Extracts username and password from input

49

2. Authenticates user via Django's authenticate()

50

3. Checks if user account is active

51

4. Generates JWT payload and token

52

5. Returns token and user data

53

"""

54

```

55

56

### Base Verification Serializer

57

58

Abstract base class providing common token validation functionality for verification and refresh operations.

59

60

```python { .api }

61

class VerificationBaseSerializer(Serializer):

62

token = CharField()

63

64

def validate(self, attrs):

65

"""

66

Abstract validation method to be implemented by subclasses.

67

68

Args:

69

attrs (dict): Input data containing token

70

71

Raises:

72

NotImplementedError: Must be overridden by subclasses

73

"""

74

75

def _check_payload(self, token):

76

"""

77

Validates JWT token and returns decoded payload.

78

79

Args:

80

token (str): JWT token string

81

82

Returns:

83

dict: Decoded JWT payload

84

85

Raises:

86

ValidationError: For expired, malformed, or invalid tokens

87

88

Validation includes:

89

- Token signature verification

90

- Expiration time checking

91

- Payload structure validation

92

"""

93

94

def _check_user(self, payload):

95

"""

96

Validates user from JWT payload and returns User instance.

97

98

Args:

99

payload (dict): Decoded JWT payload

100

101

Returns:

102

User: Active user instance

103

104

Raises:

105

ValidationError: For missing users, inactive accounts, or invalid payloads

106

107

Validation includes:

108

- Username extraction from payload

109

- User existence verification

110

- User account status checking

111

"""

112

```

113

114

### Token Verification Serializer

115

116

Validates JWT tokens and confirms their authenticity without generating new tokens.

117

118

```python { .api }

119

class VerifyJSONWebTokenSerializer(VerificationBaseSerializer):

120

def validate(self, attrs):

121

"""

122

Verifies token validity and returns token with user data.

123

124

Args:

125

attrs (dict): Input data containing token to verify

126

127

Returns:

128

dict: Contains 'token' (original JWT) and 'user' (User instance)

129

130

Raises:

131

ValidationError: For invalid, expired, or malformed tokens

132

133

Process:

134

1. Validates token signature and expiration

135

2. Extracts and validates user from payload

136

3. Returns original token and user data

137

"""

138

```

139

140

### Token Refresh Serializer

141

142

Validates existing tokens and generates new tokens with extended expiration times.

143

144

```python { .api }

145

class RefreshJSONWebTokenSerializer(VerificationBaseSerializer):

146

def validate(self, attrs):

147

"""

148

Validates token and generates refreshed token with new expiration.

149

150

Args:

151

attrs (dict): Input data containing token to refresh

152

153

Returns:

154

dict: Contains 'token' (new JWT) and 'user' (User instance)

155

156

Raises:

157

ValidationError: For invalid tokens, expired refresh windows, or missing orig_iat

158

159

Process:

160

1. Validates existing token signature and structure

161

2. Extracts and validates user from payload

162

3. Checks original issued-at time (orig_iat) for refresh eligibility

163

4. Verifies refresh hasn't exceeded maximum allowed time

164

5. Generates new token with extended expiration

165

6. Preserves original issued-at time in new token

166

167

Requirements:

168

- Token must contain 'orig_iat' field

169

- Current time must be within refresh expiration window

170

- JWT_ALLOW_REFRESH must be enabled in settings

171

"""

172

```

173

174

## Usage Examples

175

176

### Custom Authentication Serializer

177

178

```python

179

from rest_framework_jwt.serializers import JSONWebTokenSerializer

180

from rest_framework import serializers

181

from django.contrib.auth import authenticate

182

183

class CustomJWTSerializer(JSONWebTokenSerializer):

184

# Add extra fields

185

remember_me = serializers.BooleanField(default=False)

186

187

def validate(self, attrs):

188

# Get standard validation result

189

validated_data = super().validate(attrs)

190

191

# Customize token expiration based on remember_me

192

if attrs.get('remember_me'):

193

user = validated_data['user']

194

195

# Generate custom payload with longer expiration

196

from rest_framework_jwt.utils import jwt_payload_handler, jwt_encode_handler

197

from datetime import timedelta

198

199

payload = jwt_payload_handler(user)

200

payload['exp'] = payload['exp'] + timedelta(days=30) # Extend expiration

201

202

validated_data['token'] = jwt_encode_handler(payload)

203

204

return validated_data

205

```

206

207

### Custom Token Validation

208

209

```python

210

from rest_framework_jwt.serializers import VerifyJSONWebTokenSerializer

211

from rest_framework import serializers

212

213

class CustomVerifySerializer(VerifyJSONWebTokenSerializer):

214

def validate(self, attrs):

215

# Standard validation

216

validated_data = super().validate(attrs)

217

218

# Add custom business logic

219

user = validated_data['user']

220

221

# Check additional user requirements

222

if not user.profile.api_access_enabled:

223

raise serializers.ValidationError("API access is disabled for this user")

224

225

# Log token verification

226

self.log_token_verification(user, attrs['token'])

227

228

return validated_data

229

230

def log_token_verification(self, user, token):

231

# Custom logging logic

232

import logging

233

logger = logging.getLogger('jwt_auth')

234

logger.info(f"Token verified for user {user.username}")

235

```

236

237

### Manual Serializer Usage

238

239

```python

240

from rest_framework_jwt.serializers import JSONWebTokenSerializer, RefreshJSONWebTokenSerializer

241

242

# Manual authentication

243

auth_serializer = JSONWebTokenSerializer(data={

244

'username': 'testuser',

245

'password': 'testpass123'

246

})

247

248

if auth_serializer.is_valid():

249

token = auth_serializer.validated_data['token']

250

user = auth_serializer.validated_data['user']

251

print(f"Authentication successful for {user.username}")

252

else:

253

print(f"Authentication failed: {auth_serializer.errors}")

254

255

# Manual token refresh

256

refresh_serializer = RefreshJSONWebTokenSerializer(data={

257

'token': token

258

})

259

260

if refresh_serializer.is_valid():

261

new_token = refresh_serializer.validated_data['token']

262

print(f"Token refreshed successfully")

263

else:

264

print(f"Token refresh failed: {refresh_serializer.errors}")

265

```

266

267

### Integration with DRF Views

268

269

```python

270

from rest_framework.views import APIView

271

from rest_framework.response import Response

272

from rest_framework_jwt.serializers import JSONWebTokenSerializer

273

274

class CustomAuthView(APIView):

275

def post(self, request):

276

serializer = JSONWebTokenSerializer(data=request.data)

277

278

if serializer.is_valid():

279

# Custom response formatting

280

response_data = {

281

'success': True,

282

'token': serializer.validated_data['token'],

283

'user': {

284

'id': serializer.validated_data['user'].id,

285

'username': serializer.validated_data['user'].username,

286

},

287

'message': 'Authentication successful'

288

}

289

return Response(response_data)

290

else:

291

return Response({

292

'success': False,

293

'errors': serializer.errors

294

}, status=400)

295

```

296

297

## Field Validation

298

299

### Dynamic Username Field

300

301

The `JSONWebTokenSerializer` dynamically adds the username field based on your User model configuration:

302

303

```python

304

# If User.USERNAME_FIELD = 'email'

305

# Serializer will have 'email' field instead of 'username'

306

307

# If User.USERNAME_FIELD = 'username'

308

# Serializer will have 'username' field (default)

309

310

# Custom user model example

311

class CustomUser(AbstractUser):

312

email = models.EmailField(unique=True)

313

USERNAME_FIELD = 'email' # Use email for authentication

314

315

# JSONWebTokenSerializer will automatically use 'email' field

316

```

317

318

### Password Field

319

320

The password field is automatically configured with:

321

- Write-only access (not included in serialized output)

322

- Password input type for forms

323

- Required validation

324

325

## Error Handling

326

327

Serializers raise `ValidationError` for various conditions:

328

329

```python

330

from rest_framework import serializers

331

332

# Authentication errors

333

{

334

"non_field_errors": ["Unable to log in with provided credentials."]

335

}

336

337

# Field validation errors

338

{

339

"username": ["This field is required."],

340

"password": ["This field is required."]

341

}

342

343

# User account errors

344

{

345

"non_field_errors": ["User account is disabled."]

346

}

347

348

# Token validation errors

349

{

350

"token": ["This field is required."]

351

}

352

353

# JWT-specific errors

354

{

355

"non_field_errors": ["Signature has expired."]

356

}

357

{

358

"non_field_errors": ["Error decoding signature."]

359

}

360

361

# Refresh-specific errors

362

{

363

"non_field_errors": ["Refresh has expired."]

364

}

365

{

366

"non_field_errors": ["orig_iat field is required."]

367

}

368

```

369

370

## Configuration Dependencies

371

372

Serializers depend on various JWT settings:

373

374

- `JWT_PAYLOAD_HANDLER`: Function to generate JWT payloads

375

- `JWT_ENCODE_HANDLER`: Function to encode JWT tokens

376

- `JWT_DECODE_HANDLER`: Function to decode JWT tokens

377

- `JWT_PAYLOAD_GET_USERNAME_HANDLER`: Function to extract username from payload

378

- `JWT_ALLOW_REFRESH`: Enable/disable token refresh functionality

379

- `JWT_REFRESH_EXPIRATION_DELTA`: Maximum time allowed for token refresh

380

381

These settings control the behavior of token generation, validation, and refresh operations within the serializers.

382

383

## Module Variables

384

385

The serializers module defines several handler function references and the User model:

386

387

```python { .api }

388

User = get_user_model()

389

"""Reference to the configured Django User model."""

390

391

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER

392

"""Function reference for generating JWT payloads from user instances."""

393

394

jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

395

"""Function reference for encoding JWT tokens."""

396

397

jwt_decode_handler = api_settings.JWT_DECODE_HANDLER

398

"""Function reference for decoding JWT tokens."""

399

400

jwt_get_username_from_payload = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLER

401

"""Function reference for extracting username from JWT payload."""

402

```