0
# User Registration & Confirmation
1
2
User registration forms, email confirmation workflow, account activation functionality, and user account management for onboarding new users to Flask applications.
3
4
## Capabilities
5
6
### Registration Forms
7
8
Forms for user registration with various configurations and validation options.
9
10
```python { .api }
11
class RegisterForm(Form):
12
"""
13
Basic user registration form.
14
15
Fields:
16
- email: Email address field with validation
17
- password: Password field with confirmation
18
- password_confirm: Password confirmation field
19
- submit: Submit button
20
"""
21
email: StringField
22
password: PasswordField
23
password_confirm: PasswordField
24
submit: SubmitField
25
26
class RegisterFormV2(Form):
27
"""
28
Enhanced registration form with additional features.
29
30
Fields:
31
- email: Email address field
32
- username: Username field (if username is enabled)
33
- password: Password field
34
- password_confirm: Password confirmation field
35
- submit: Submit button
36
"""
37
email: StringField
38
username: StringField
39
password: PasswordField
40
password_confirm: PasswordField
41
submit: SubmitField
42
43
class ConfirmRegisterForm(Form):
44
"""
45
Registration form requiring email confirmation.
46
47
Fields:
48
- email: Email address field
49
- password: Password field
50
- password_confirm: Password confirmation field
51
- submit: Submit button
52
"""
53
email: StringField
54
password: PasswordField
55
password_confirm: PasswordField
56
submit: SubmitField
57
```
58
59
### User Registration Functions
60
61
Core functions for registering new users and managing the registration process.
62
63
```python { .api }
64
def register_user(**kwargs):
65
"""
66
Register a new user with provided attributes.
67
68
Parameters:
69
- email: User's email address
70
- password: User's password (will be hashed)
71
- username: Username (optional, if enabled)
72
- active: Whether user should be active immediately (default: True)
73
- confirmed_at: Confirmation timestamp (optional)
74
- roles: List of roles to assign to user (optional)
75
- **kwargs: Additional user attributes
76
77
Returns:
78
Created user object
79
80
Raises:
81
UserAlreadyExistsError: If user with email already exists
82
"""
83
84
def register_existing(user, **kwargs):
85
"""
86
Handle registration attempt for existing user (e.g., OAuth scenarios).
87
88
Parameters:
89
- user: Existing user object
90
- **kwargs: Additional attributes to update
91
92
Returns:
93
Updated user object
94
"""
95
```
96
97
### Email Confirmation Functions
98
99
Functions for managing email confirmation workflow and account activation.
100
101
```python { .api }
102
def send_confirmation_instructions(user):
103
"""
104
Send email confirmation instructions to user.
105
106
Parameters:
107
- user: User object to send confirmation to
108
109
Returns:
110
True if email sent successfully, False otherwise
111
"""
112
113
def generate_confirmation_token(user):
114
"""
115
Generate email confirmation token for user.
116
117
Parameters:
118
- user: User object to generate token for
119
120
Returns:
121
Confirmation token string
122
"""
123
124
def generate_confirmation_link(user):
125
"""
126
Generate email confirmation URL for user.
127
128
Parameters:
129
- user: User object to generate link for
130
131
Returns:
132
Full confirmation URL string
133
"""
134
135
def confirm_user(user):
136
"""
137
Confirm user's email address and activate account.
138
139
Parameters:
140
- user: User object to confirm
141
142
Returns:
143
True if user confirmed successfully, False otherwise
144
"""
145
146
def confirm_email_token_status(token):
147
"""
148
Validate email confirmation token and return status.
149
150
Parameters:
151
- token: Confirmation token to validate
152
153
Returns:
154
Tuple of (expired: bool, invalid: bool, user: User|None)
155
"""
156
157
def requires_confirmation(user):
158
"""
159
Check if user requires email confirmation.
160
161
Parameters:
162
- user: User object to check
163
164
Returns:
165
True if user needs confirmation, False otherwise
166
"""
167
```
168
169
### Email Confirmation Forms
170
171
Forms for handling email confirmation workflow.
172
173
```python { .api }
174
class SendConfirmationForm(Form):
175
"""
176
Form for sending/resending email confirmation.
177
178
Fields:
179
- user: Email or username field
180
- submit: Submit button
181
"""
182
user: StringField
183
submit: SubmitField
184
```
185
186
### Registration Form Mixins
187
188
Reusable mixins for building custom registration forms.
189
190
```python { .api }
191
class RegisterFormMixin:
192
"""
193
Base mixin for registration forms providing common functionality.
194
"""
195
196
class UserEmailFormMixin:
197
"""
198
Mixin providing email field with validation.
199
"""
200
201
class UniqueEmailFormMixin:
202
"""
203
Mixin providing email uniqueness validation.
204
"""
205
206
class PasswordFormMixin:
207
"""
208
Mixin providing password field with validation.
209
"""
210
211
class NewPasswordFormMixin:
212
"""
213
Mixin providing new password field with confirmation.
214
"""
215
216
class PasswordConfirmFormMixin:
217
"""
218
Mixin providing password confirmation field and validation.
219
"""
220
```
221
222
### Form Building Functions
223
224
Dynamic form building functions for customizing registration forms.
225
226
```python { .api }
227
def build_register_form(base_class=RegisterForm):
228
"""
229
Build registration form class with current configuration.
230
231
Parameters:
232
- base_class: Base form class to extend (default: RegisterForm)
233
234
Returns:
235
Dynamically created form class
236
"""
237
238
def unique_identity_attribute(form, field):
239
"""
240
Validator for ensuring unique identity attributes (email, username).
241
242
Parameters:
243
- form: Form instance
244
- field: Field being validated
245
246
Raises:
247
ValidationError: If identity attribute is not unique
248
"""
249
```
250
251
## Usage Examples
252
253
### Basic Registration Setup
254
255
```python
256
from flask_security import Security, RegisterForm
257
258
# Enable registration in configuration
259
app.config['SECURITY_REGISTERABLE'] = True
260
261
# Use default registration form
262
security = Security(app, user_datastore)
263
264
# Access registration URL: /register
265
```
266
267
### Custom Registration Form
268
269
```python
270
from flask_security import RegisterForm
271
from wtforms import StringField, TextAreaField
272
from wtforms.validators import DataRequired, Length
273
274
class ExtendedRegisterForm(RegisterForm):
275
first_name = StringField('First Name', validators=[DataRequired()])
276
last_name = StringField('Last Name', validators=[DataRequired()])
277
bio = TextAreaField('Bio', validators=[Length(max=500)])
278
279
# Use custom form
280
security = Security(app, user_datastore, register_form=ExtendedRegisterForm)
281
```
282
283
### Registration with Email Confirmation
284
285
```python
286
# Enable confirmable feature
287
app.config['SECURITY_CONFIRMABLE'] = True
288
app.config['SECURITY_CONFIRM_EMAIL_WITHIN'] = '5 days'
289
290
# Use confirmation registration form
291
security = Security(app, user_datastore, confirm_register_form=ConfirmRegisterForm)
292
```
293
294
### Programmatic User Registration
295
296
```python
297
from flask_security import register_user, hash_password
298
299
@app.route('/admin/create-user', methods=['POST'])
300
@roles_required('admin')
301
def create_user():
302
email = request.form['email']
303
password = request.form['password']
304
305
try:
306
user = register_user(
307
email=email,
308
password=password,
309
active=True,
310
confirmed_at=datetime.utcnow(),
311
roles=['user']
312
)
313
db.session.commit()
314
flash(f'User {email} created successfully')
315
return redirect('/admin/users')
316
except Exception as e:
317
flash(f'Error creating user: {str(e)}')
318
return redirect('/admin/create-user')
319
```
320
321
### Manual Email Confirmation
322
323
```python
324
from flask_security import send_confirmation_instructions, confirm_user
325
326
@app.route('/resend-confirmation')
327
@login_required
328
def resend_confirmation():
329
if requires_confirmation(current_user):
330
send_confirmation_instructions(current_user)
331
flash('Confirmation instructions sent to your email')
332
else:
333
flash('Your email is already confirmed')
334
return redirect('/profile')
335
336
@app.route('/admin/confirm-user/<int:user_id>')
337
@roles_required('admin')
338
def admin_confirm_user(user_id):
339
user = User.query.get_or_404(user_id)
340
if confirm_user(user):
341
db.session.commit()
342
flash(f'User {user.email} confirmed successfully')
343
else:
344
flash('User was already confirmed')
345
return redirect('/admin/users')
346
```
347
348
### Registration with Role Assignment
349
350
```python
351
from flask_security import register_user, find_role
352
353
@app.route('/register-teacher', methods=['POST'])
354
def register_teacher():
355
# Custom registration endpoint for teachers
356
form = TeacherRegistrationForm()
357
if form.validate_on_submit():
358
teacher_role = find_role('teacher')
359
user = register_user(
360
email=form.email.data,
361
password=form.password.data,
362
first_name=form.first_name.data,
363
last_name=form.last_name.data,
364
school=form.school.data,
365
roles=[teacher_role],
366
active=False, # Require admin approval
367
)
368
db.session.commit()
369
370
# Send notification to admins
371
send_teacher_registration_notification(user)
372
373
flash('Registration submitted for approval')
374
return redirect('/login')
375
376
return render_template('register_teacher.html', form=form)
377
```
378
379
### Registration Hooks and Customization
380
381
```python
382
from flask_security.signals import user_registered
383
384
@user_registered.connect_via(app)
385
def user_registered_sighandler(sender, **extra):
386
user = extra['user']
387
388
# Send welcome email
389
send_welcome_email(user)
390
391
# Log registration
392
app.logger.info(f'New user registered: {user.email}')
393
394
# Add to mailing list (example)
395
subscribe_to_newsletter(user.email)
396
```
397
398
### Email Confirmation Customization
399
400
```python
401
from flask_security import confirm_email_token_status
402
403
@app.route('/confirm/<token>')
404
def confirm_email(token):
405
expired, invalid, user = confirm_email_token_status(token)
406
407
if expired:
408
flash('The confirmation link has expired')
409
return redirect('/resend-confirmation')
410
411
if invalid or not user:
412
flash('Invalid confirmation link')
413
return redirect('/login')
414
415
if user.confirmed_at:
416
flash('Email already confirmed')
417
else:
418
confirm_user(user)
419
db.session.commit()
420
flash('Email confirmed successfully! You can now log in.')
421
422
return redirect('/login')
423
```
424
425
### Registration Form Validation
426
427
```python
428
from wtforms.validators import ValidationError
429
from flask_security import unique_identity_attribute
430
431
class CustomRegisterForm(RegisterForm):
432
company = StringField('Company', validators=[DataRequired()])
433
434
def validate_email(self, field):
435
# Custom email domain validation
436
allowed_domains = ['company.com', 'partner.com']
437
domain = field.data.split('@')[1].lower()
438
if domain not in allowed_domains:
439
raise ValidationError('Email must be from an approved domain')
440
441
def validate_company(self, field):
442
# Custom company validation
443
valid_companies = ['ACME Corp', 'Global Inc', 'Tech Solutions']
444
if field.data not in valid_companies:
445
raise ValidationError('Invalid company selection')
446
```
447
448
## Configuration Options
449
450
Key configuration variables for registration and confirmation:
451
452
```python
453
# Registration settings
454
app.config['SECURITY_REGISTERABLE'] = True
455
app.config['SECURITY_REGISTER_URL'] = '/register'
456
app.config['SECURITY_POST_REGISTER_REDIRECT_ENDPOINT'] = '/profile'
457
458
# Email confirmation settings
459
app.config['SECURITY_CONFIRMABLE'] = True
460
app.config['SECURITY_CONFIRM_EMAIL_WITHIN'] = '5 days'
461
app.config['SECURITY_CONFIRM_URL'] = '/confirm'
462
app.config['SECURITY_POST_CONFIRM_REDIRECT_ENDPOINT'] = '/profile'
463
464
# Auto-login after registration/confirmation
465
app.config['SECURITY_AUTO_LOGIN_AFTER_CONFIRM'] = True
466
app.config['SECURITY_AUTO_LOGIN_AFTER_REGISTER'] = False
467
```