0
# Core Authentication API
1
2
Core functions for managing OTP authentication, including user login, token verification, and device management. These functions form the foundation of django-otp's authentication system.
3
4
## Capabilities
5
6
### Session Management
7
8
#### login
9
10
Persist the given OTP device in the current session, linking it to the authenticated user.
11
12
```python { .api }
13
def login(request, device):
14
"""
15
Persist the given OTP device in the current session.
16
17
Parameters:
18
- request: HttpRequest - The HTTP request object
19
- device: Device - The OTP device used to verify the user
20
21
Returns:
22
None
23
"""
24
```
25
26
The device will be rejected if it does not belong to `request.user`. This is called automatically when `django.contrib.auth.login` is called with a user having an `otp_device` attribute.
27
28
### Token Verification
29
30
#### verify_token
31
32
Attempts to verify a token against a specific device, identified by its persistent ID.
33
34
```python { .api }
35
def verify_token(user, device_id, token):
36
"""
37
Attempts to verify a token against a specific device.
38
39
Parameters:
40
- user: User - The user supplying the token
41
- device_id: str - A device's persistent_id value
42
- token: str - An OTP token to verify
43
44
Returns:
45
Device or None - The device that accepted the token, if any
46
"""
47
```
48
49
This wraps the verification process in a database transaction to ensure that security policies like throttling are properly enforced.
50
51
#### match_token (Deprecated)
52
53
Attempts to verify a token on every device attached to the given user until one succeeds.
54
55
```python { .api }
56
def match_token(user, token):
57
"""
58
Attempts to verify a token on every device attached to the user.
59
60
WARNING: This function is deprecated and not recommended for use.
61
It may not interact well with recent features like throttling.
62
63
Parameters:
64
- user: User - The user supplying the token
65
- token: str - An OTP token to verify
66
67
Returns:
68
Device or None - The device that accepted the token, if any
69
"""
70
```
71
72
### Device Management
73
74
#### devices_for_user
75
76
Return an iterable of all devices registered to the given user.
77
78
```python { .api }
79
def devices_for_user(user, confirmed=True, for_verify=False):
80
"""
81
Return an iterable of all devices registered to the given user.
82
83
Parameters:
84
- user: User - Standard or custom user object
85
- confirmed: bool or None - If None, all matching devices are returned.
86
Otherwise, limit to confirmed/unconfirmed devices
87
- for_verify: bool - If True, load devices with select_for_update to prevent
88
concurrent verifications. Must be called inside a transaction
89
90
Returns:
91
Generator yielding Device instances
92
"""
93
```
94
95
Returns an empty iterable for anonymous users.
96
97
#### user_has_device
98
99
Return `True` if the user has at least one device.
100
101
```python { .api }
102
def user_has_device(user, confirmed=True):
103
"""
104
Return True if the user has at least one device.
105
106
Parameters:
107
- user: User - Standard or custom user object
108
- confirmed: bool or None - If None, all matching devices are considered.
109
Otherwise, limit to confirmed/unconfirmed devices
110
111
Returns:
112
bool - True if user has at least one matching device
113
"""
114
```
115
116
Returns `False` for anonymous users.
117
118
#### device_classes
119
120
Returns an iterable of all loaded device models.
121
122
```python { .api }
123
def device_classes():
124
"""
125
Returns an iterable of all loaded device models.
126
127
Returns:
128
Generator yielding Device model classes
129
"""
130
```
131
132
Useful for discovering all available OTP device types in the current Django installation.
133
134
## Constants
135
136
```python { .api }
137
DEVICE_ID_SESSION_KEY = 'otp_device_id'
138
```
139
140
Session key used to store the persistent ID of the user's current OTP device.
141
142
## Usage Examples
143
144
### Basic Authentication Flow
145
146
```python
147
from django_otp import login, verify_token, devices_for_user
148
from django.contrib.auth import authenticate
149
from django.contrib.auth import login as auth_login
150
151
def two_factor_login(request, username, password, otp_token, device_id):
152
# First, authenticate with username/password
153
user = authenticate(request, username=username, password=password)
154
if not user:
155
return None, "Invalid credentials"
156
157
# Then verify OTP token
158
device = verify_token(user, device_id, otp_token)
159
if not device:
160
return None, "Invalid OTP token"
161
162
# Complete the login process
163
auth_login(request, user)
164
login(request, device) # This persists the OTP device
165
166
return user, "Login successful"
167
```
168
169
### Device Enumeration
170
171
```python
172
from django_otp import devices_for_user, user_has_device
173
174
def get_user_devices(user):
175
if not user_has_device(user):
176
return []
177
178
devices = []
179
for device in devices_for_user(user):
180
devices.append({
181
'id': device.persistent_id,
182
'name': device.name,
183
'type': device.__class__.__name__,
184
'confirmed': device.confirmed
185
})
186
187
return devices
188
```
189
190
### Custom Device Discovery
191
192
```python
193
from django_otp import device_classes
194
195
def list_available_device_types():
196
types = []
197
for device_class in device_classes():
198
types.append({
199
'model': device_class.__name__,
200
'app_label': device_class._meta.app_label,
201
'verbose_name': device_class._meta.verbose_name
202
})
203
return types
204
```