1FLASK-SECURITY(1) Flask-Security FLASK-SECURITY(1)
2
3
4
6 flask-security - Flask-Security Documentation
7
8 Flask-Security allows you to quickly add common security mechanisms to
9 your Flask application. They include:
10
11 1. Session based authentication
12
13 2. Role management
14
15 3. Password hashing
16
17 4. Basic HTTP authentication
18
19 5. Token based authentication
20
21 6. Token based account activation (optional)
22
23 7. Token based password recovery / resetting (optional)
24
25 8. User registration (optional)
26
27 9. Login tracking (optional)
28
29 10. JSON/Ajax Support
30
31 Many of these features are made possible by integrating various Flask
32 extensions and libraries. They include:
33
34 1. Flask-Login
35
36 2. Flask-Mail
37
38 3. Flask-Principal
39
40 4. Flask-WTF
41
42 5. itsdangerous
43
44 6. passlib
45
46 Additionally, it assumes you’ll be using a common library for your
47 database connections and model definitions. Flask-Security supports the
48 following Flask extensions out of the box for data persistence:
49
50 1. Flask-SQLAlchemy
51
52 2. Flask-MongoEngine
53
54 3. Flask-Peewee
55
56 4. PonyORM
57
59 Features
60 Flask-Security allows you to quickly add common security mechanisms to
61 your Flask application. They include:
62
63 Session Based Authentication
64 Session based authentication is fulfilled entirely by the Flask-Login
65 extension. Flask-Security handles the configuration of Flask-Login
66 automatically based on a few of its own configuration values and uses
67 Flask-Login’s alternative token feature for remembering users when
68 their session has expired.
69
70 Role/Identity Based Access
71 Flask-Security implements very basic role management out of the box.
72 This means that you can associate a high level role or multiple roles
73 to any user. For instance, you may assign roles such as Admin, Editor,
74 SuperUser, or a combination of said roles to a user. Access control is
75 based on the role name and all roles should be uniquely named. This
76 feature is implemented using the Flask-Principal extension. If you’d
77 like to implement more granular access control, you can refer to the
78 Flask-Principal documentation on this topic.
79
80 Password Hashing
81 Password hashing is enabled with passlib. Passwords are hashed with the
82 bcrypt function by default but you can easily configure the hashing
83 algorithm. You should always use an hashing algorithm in your produc‐
84 tion environment. You may also specify to use HMAC with a configured
85 salt value in addition to the algorithm chosen. Bear in mind passlib
86 does not assume which algorithm you will choose and may require addi‐
87 tional libraries to be installed.
88
89 Basic HTTP Authentication
90 Basic HTTP authentication is achievable using a simple view method dec‐
91 orator. This feature expects the incoming authentication information
92 to identify a user in the system. This means that the username must be
93 equal to their email address.
94
95 Token Authentication
96 Token based authentication is enabled by retrieving the user auth token
97 by performing an HTTP POST with the authentication details as JSON data
98 against the authentication endpoint. A successful call to this endpoint
99 will return the user’s ID and their authentication token. This token
100 can be used in subsequent requests to protected resources. The auth
101 token is supplied in the request through an HTTP header or query string
102 parameter. By default the HTTP header name is Authentication-Token and
103 the default query string parameter name is auth_token. Authentication
104 tokens are generated using the user’s password. Thus if the user
105 changes his or her password their existing authentication token will
106 become invalid. A new token will need to be retrieved using the user’s
107 new password.
108
109 Email Confirmation
110 If desired you can require that new users confirm their email address.
111 Flask-Security will send an email message to any new users with a con‐
112 firmation link. Upon navigating to the confirmation link, the user will
113 be automatically logged in. There is also view for resending a confir‐
114 mation link to a given email if the user happens to try to use an
115 expired token or has lost the previous email. Confirmation links can be
116 configured to expire after a specified amount of time.
117
118 Password Reset/Recovery
119 Password reset and recovery is available for when a user forgets his or
120 her password. Flask-Security sends an email to the user with a link to
121 a view which they can reset their password. Once the password is reset
122 they are automatically logged in and can use the new password from then
123 on. Password reset links can be configured to expire after a specified
124 amount of time.
125
126 User Registration
127 Flask-Security comes packaged with a basic user registration view. This
128 view is very simple and new users need only supply an email address and
129 their password. This view can be overridden if your registration
130 process requires more fields.
131
132 Login Tracking
133 Flask-Security can, if configured, keep track of basic login events and
134 statistics. They include:
135
136 · Last login date
137
138 · Current login date
139
140 · Last login IP address
141
142 · Current login IP address
143
144 · Total login count
145
146 JSON/Ajax Support
147 Flask-Security supports JSON/Ajax requests where appropriate. Just
148 remember that all endpoints require a CSRF token just like HTML views.
149 More specifically JSON is supported for the following operations:
150
151 · Login requests
152
153 · Registration requests
154
155 · Change password requests
156
157 · Confirmation requests
158
159 · Forgot password requests
160
161 · Passwordless login requests
162
163 Command Line Interface
164 Basic Click commands for managing users and roles are automatically
165 registered. They can be completely disabled or their names can be
166 changed. Run flask --help and look for users and roles.
167
168 Configuration
169 The following configuration values are used by Flask-Security:
170
171 Core
172 ┌─────────────────────────────┬────────────────────────────┐
173 │SECURITY_BLUEPRINT_NAME │ Specifies the name for the │
174 │ │ Flask-Security blueprint. │
175 │ │ Defaults to security. │
176 ├─────────────────────────────┼────────────────────────────┤
177 │SECURITY_CLI_USERS_NAME │ Specifies the name for the │
178 │ │ command managing users. │
179 │ │ Disable by setting False. │
180 │ │ Defaults to users. │
181 ├─────────────────────────────┼────────────────────────────┤
182 │SECURITY_CLI_ROLES_NAME │ Specifies the name for the │
183 │ │ command managing roles. │
184 │ │ Disable by setting False. │
185 │ │ Defaults to roles. │
186 ├─────────────────────────────┼────────────────────────────┤
187 │SECURITY_URL_PREFIX │ Specifies the URL prefix │
188 │ │ for the Flask-Security │
189 │ │ blueprint. Defaults to │
190 │ │ None. │
191 ├─────────────────────────────┼────────────────────────────┤
192 │SECURITY_SUBDOMAIN │ Specifies the subdomain │
193 │ │ for the Flask-Security │
194 │ │ blueprint. Defaults to │
195 │ │ None. │
196 ├─────────────────────────────┼────────────────────────────┤
197 │SECURITY_FLASH_MESSAGES │ Specifies whether or not │
198 │ │ to flash messages during │
199 │ │ security procedures. │
200 │ │ Defaults to True. │
201 └─────────────────────────────┴────────────────────────────┘
202
203 │SECURITY_I18N_DOMAIN │ Specifies the name for │
204 │ │ domain used for transla‐ │
205 │ │ tions. Defaults to │
206 │ │ flask_security. │
207 ├─────────────────────────────┼────────────────────────────┤
208 │SECURITY_PASSWORD_HASH │ Specifies the password │
209 │ │ hash algorithm to use when │
210 │ │ hashing passwords. Recom‐ │
211 │ │ mended values for produc‐ │
212 │ │ tion systems are bcrypt, │
213 │ │ sha512_crypt, or │
214 │ │ pbkdf2_sha512. Defaults to │
215 │ │ bcrypt. │
216 ├─────────────────────────────┼────────────────────────────┤
217 │SECURITY_PASSWORD_SALT │ Specifies the HMAC salt. │
218 │ │ This is only used if the │
219 │ │ password hash type is set │
220 │ │ to something other than │
221 │ │ plain text. Defaults to │
222 │ │ None. │
223 ├─────────────────────────────┼────────────────────────────┤
224 │SECURITY_PASSWORD_SIN‐ │ Specifies that passwords │
225 │GLE_HASH │ should only be hashed │
226 │ │ once. By default, pass‐ │
227 │ │ words are hashed twice, │
228 │ │ first with SECURITY_PASS‐ │
229 │ │ WORD_SALT, and then with a │
230 │ │ random salt. May be useful │
231 │ │ for integrating with other │
232 │ │ applications. Defaults to │
233 │ │ False. │
234 ├─────────────────────────────┼────────────────────────────┤
235 │SECURITY_HASHING_SCHEMES │ List of algorithms used │
236 │ │ for creating and validat‐ │
237 │ │ ing tokens. Defaults to │
238 │ │ sha256_crypt. │
239 ├─────────────────────────────┼────────────────────────────┤
240 │SECURITY_DEPRECATED_HASH‐ │ List of deprecated algo‐ │
241 │ING_SCHEMES │ rithms used for creating │
242 │ │ and validating tokens. │
243 │ │ Defaults to hex_md5. │
244 ├─────────────────────────────┼────────────────────────────┤
245 │SECURITY_PASS‐ │ Specifies additional │
246 │WORD_HASH_OPTIONS │ options to be passed to │
247 │ │ the hashing method. │
248 ├─────────────────────────────┼────────────────────────────┤
249 │SECURITY_EMAIL_SENDER │ Specifies the email │
250 │ │ address to send emails as. │
251 │ │ Defaults to value set to │
252 │ │ MAIL_DEFAULT_SENDER if │
253 │ │ Flask-Mail is used other‐ │
254 │ │ wise no-reply@localhost. │
255 ├─────────────────────────────┼────────────────────────────┤
256 │SECURITY_TOKEN_AUTHENTICA‐ │ Specifies the query string │
257 │TION_KEY │ parameter to read when │
258 │ │ using token authentica‐ │
259 │ │ tion. Defaults to │
260 │ │ auth_token. │
261 ├─────────────────────────────┼────────────────────────────┤
262 │SECURITY_TOKEN_AUTHENTICA‐ │ Specifies the HTTP header │
263 │TION_HEADER │ to read when using token │
264 │ │ authentication. Defaults │
265 │ │ to Authentication-Token. │
266 └─────────────────────────────┴────────────────────────────┘
267
268
269
270
271 │SECURITY_TOKEN_MAX_AGE │ Specifies the number of │
272 │ │ seconds before an authen‐ │
273 │ │ tication token expires. │
274 │ │ Defaults to None, meaning │
275 │ │ the token never expires. │
276 ├─────────────────────────────┼────────────────────────────┤
277 │SECU‐ │ Specifies the default │
278 │RITY_DEFAULT_HTTP_AUTH_REALM │ authentication realm when │
279 │ │ using basic HTTP auth. │
280 │ │ Defaults to Login Required │
281 └─────────────────────────────┴────────────────────────────┘
282
283 URLs and Views
284 ┌───────────────────────────┬────────────────────────────┐
285 │SECURITY_LOGIN_URL │ Specifies the login URL. │
286 │ │ Defaults to /login. │
287 ├───────────────────────────┼────────────────────────────┤
288 │SECURITY_LOGOUT_URL │ Specifies the logout URL. │
289 │ │ Defaults to /logout. │
290 ├───────────────────────────┼────────────────────────────┤
291 │SECURITY_REGISTER_URL │ Specifies the register │
292 │ │ URL. Defaults to /regis‐ │
293 │ │ ter. │
294 ├───────────────────────────┼────────────────────────────┤
295 │SECURITY_RESET_URL │ Specifies the password │
296 │ │ reset URL. Defaults to │
297 │ │ /reset. │
298 ├───────────────────────────┼────────────────────────────┤
299 │SECURITY_CHANGE_URL │ Specifies the password │
300 │ │ change URL. Defaults to │
301 │ │ /change. │
302 ├───────────────────────────┼────────────────────────────┤
303 │SECURITY_CONFIRM_URL │ Specifies the email con‐ │
304 │ │ firmation URL. Defaults to │
305 │ │ /confirm. │
306 ├───────────────────────────┼────────────────────────────┤
307 │SECURITY_POST_LOGIN_VIEW │ Specifies the default view │
308 │ │ to redirect to after a │
309 │ │ user logs in. This value │
310 │ │ can be set to a URL or an │
311 │ │ endpoint name. Defaults to │
312 │ │ /. │
313 ├───────────────────────────┼────────────────────────────┤
314 │SECURITY_POST_LOGOUT_VIEW │ Specifies the default view │
315 │ │ to redirect to after a │
316 │ │ user logs out. This value │
317 │ │ can be set to a URL or an │
318 │ │ endpoint name. Defaults to │
319 │ │ /. │
320 ├───────────────────────────┼────────────────────────────┤
321 │SECURITY_CON‐ │ Specifies the view to re‐ │
322 │FIRM_ERROR_VIEW │ direct to if a confirma‐ │
323 │ │ tion error occurs. This │
324 │ │ value can be set to a URL │
325 │ │ or an endpoint name. If │
326 │ │ this value is None, the │
327 │ │ user is presented the │
328 │ │ default view to resend a │
329 │ │ confirmation link. │
330 │ │ Defaults to None. │
331 └───────────────────────────┴────────────────────────────┘
332
333
334
335
336
337
338
339 │SECURITY_POST_REGIS‐ │ Specifies the view to re‐ │
340 │TER_VIEW │ direct to after a user │
341 │ │ successfully registers. │
342 │ │ This value can be set to a │
343 │ │ URL or an endpoint name. │
344 │ │ If this value is None, the │
345 │ │ user is redirected to the │
346 │ │ value of SECU‐ │
347 │ │ RITY_POST_LOGIN_VIEW. │
348 │ │ Defaults to None. │
349 ├───────────────────────────┼────────────────────────────┤
350 │SECURITY_POST_CONFIRM_VIEW │ Specifies the view to re‐ │
351 │ │ direct to after a user │
352 │ │ successfully confirms │
353 │ │ their email. This value │
354 │ │ can be set to a URL or an │
355 │ │ endpoint name. If this │
356 │ │ value is None, the user is │
357 │ │ redirected to the value │
358 │ │ of SECU‐ │
359 │ │ RITY_POST_LOGIN_VIEW. │
360 │ │ Defaults to None. │
361 ├───────────────────────────┼────────────────────────────┤
362 │SECURITY_POST_RESET_VIEW │ Specifies the view to re‐ │
363 │ │ direct to after a user │
364 │ │ successfully resets their │
365 │ │ password. This value can │
366 │ │ be set to a URL or an end‐ │
367 │ │ point name. If this value │
368 │ │ is None, the user is redi‐ │
369 │ │ rected to the value of │
370 │ │ SECURITY_POST_LOGIN_VIEW. │
371 │ │ Defaults to None. │
372 ├───────────────────────────┼────────────────────────────┤
373 │SECURITY_POST_CHANGE_VIEW │ Specifies the view to re‐ │
374 │ │ direct to after a user │
375 │ │ successfully changes their │
376 │ │ password. This value can │
377 │ │ be set to a URL or an end‐ │
378 │ │ point name. If this value │
379 │ │ is None, the user is redi‐ │
380 │ │ rected to the value of │
381 │ │ SECURITY_POST_LOGIN_VIEW. │
382 │ │ Defaults to None. │
383 ├───────────────────────────┼────────────────────────────┤
384 │SECURITY_UNAUTHORIZED_VIEW │ Specifies the view to re‐ │
385 │ │ direct to if a user │
386 │ │ attempts to access a │
387 │ │ URL/endpoint that they do │
388 │ │ not have permission to │
389 │ │ access. If this value is │
390 │ │ None, the user is pre‐ │
391 │ │ sented with a default HTTP │
392 │ │ 403 response. Defaults to │
393 │ │ None. │
394 └───────────────────────────┴────────────────────────────┘
395
396 Template Paths
397 ┌─────────────────────────┬────────────────────────────┐
398 │SECURITY_FORGOT_PASS‐ │ Specifies the path to the │
399 │WORD_TEMPLATE │ template for the forgot │
400 │ │ password page. Defaults to │
401 │ │ security/forgot_pass‐ │
402 │ │ word.html. │
403 └─────────────────────────┴────────────────────────────┘
404
405
406
407 │SECURITY_LOGIN_USER_TEM‐ │ Specifies the path to the │
408 │PLATE │ template for the user │
409 │ │ login page. Defaults to │
410 │ │ security/login_user.html. │
411 ├─────────────────────────┼────────────────────────────┤
412 │SECURITY_REGIS‐ │ Specifies the path to the │
413 │TER_USER_TEMPLATE │ template for the user reg‐ │
414 │ │ istration page. Defaults │
415 │ │ to security/regis‐ │
416 │ │ ter_user.html. │
417 ├─────────────────────────┼────────────────────────────┤
418 │SECURITY_RESET_PASS‐ │ Specifies the path to the │
419 │WORD_TEMPLATE │ template for the reset │
420 │ │ password page. Defaults to │
421 │ │ security/reset_pass‐ │
422 │ │ word.html. │
423 ├─────────────────────────┼────────────────────────────┤
424 │SECURITY_CHANGE_PASS‐ │ Specifies the path to the │
425 │WORD_TEMPLATE │ template for the change │
426 │ │ password page. Defaults to │
427 │ │ security/change_pass‐ │
428 │ │ word.html. │
429 ├─────────────────────────┼────────────────────────────┤
430 │SECURITY_SEND_CONFIRMA‐ │ Specifies the path to the │
431 │TION_TEMPLATE │ template for the resend │
432 │ │ confirmation instructions │
433 │ │ page. Defaults to secu‐ │
434 │ │ rity/send_confirma‐ │
435 │ │ tion.html. │
436 ├─────────────────────────┼────────────────────────────┤
437 │SECURITY_SEND_LOGIN_TEM‐ │ Specifies the path to the │
438 │PLATE │ template for the send │
439 │ │ login instructions page │
440 │ │ for passwordless logins. │
441 │ │ Defaults to secu‐ │
442 │ │ rity/send_login.html. │
443 └─────────────────────────┴────────────────────────────┘
444
445 Feature Flags
446 ┌──────────────────────┬────────────────────────────┐
447 │SECURITY_CONFIRMABLE │ Specifies if users are │
448 │ │ required to confirm their │
449 │ │ email address when regis‐ │
450 │ │ tering a new account. If │
451 │ │ this value is True, │
452 │ │ Flask-Security creates an │
453 │ │ endpoint to handle confir‐ │
454 │ │ mations and requests to │
455 │ │ resend confirmation │
456 │ │ instructions. The URL for │
457 │ │ this endpoint is specified │
458 │ │ by the SECURITY_CON‐ │
459 │ │ FIRM_URL configuration │
460 │ │ option. Defaults to │
461 │ │ False. │
462 ├──────────────────────┼────────────────────────────┤
463 │SECURITY_REGISTERABLE │ Specifies if Flask-Secu‐ │
464 │ │ rity should create a user │
465 │ │ registration endpoint. The │
466 │ │ URL for this endpoint is │
467 │ │ specified by the SECU‐ │
468 │ │ RITY_REGISTER_URL configu‐ │
469 │ │ ration option. Defaults to │
470 │ │ False. │
471 └──────────────────────┴────────────────────────────┘
472
473
474
475 │SECURITY_RECOVERABLE │ Specifies if Flask-Secu‐ │
476 │ │ rity should create a pass‐ │
477 │ │ word reset/recover end‐ │
478 │ │ point. The URL for this │
479 │ │ endpoint is specified by │
480 │ │ the SECURITY_RESET_URL │
481 │ │ configuration option. │
482 │ │ Defaults to False. │
483 ├──────────────────────┼────────────────────────────┤
484 │SECURITY_TRACKABLE │ Specifies if Flask-Secu‐ │
485 │ │ rity should track basic │
486 │ │ user login statistics. If │
487 │ │ set to True, ensure your │
488 │ │ models have the required │
489 │ │ fields/attributes. Be sure │
490 │ │ to use ProxyFix if you are │
491 │ │ using a proxy. Defaults to │
492 │ │ False │
493 ├──────────────────────┼────────────────────────────┤
494 │SECURITY_PASSWORDLESS │ Specifies if Flask-Secu‐ │
495 │ │ rity should enable the │
496 │ │ passwordless login fea‐ │
497 │ │ ture. If set to True, │
498 │ │ users are not required to │
499 │ │ enter a password to login │
500 │ │ but are sent an email with │
501 │ │ a login link. This feature │
502 │ │ is experimental and should │
503 │ │ be used with caution. │
504 │ │ Defaults to False. │
505 ├──────────────────────┼────────────────────────────┤
506 │SECURITY_CHANGEABLE │ Specifies if Flask-Secu‐ │
507 │ │ rity should enable the │
508 │ │ change password endpoint. │
509 │ │ The URL for this endpoint │
510 │ │ is specified by the SECU‐ │
511 │ │ RITY_CHANGE_URL configura‐ │
512 │ │ tion option. Defaults to │
513 │ │ False. │
514 └──────────────────────┴────────────────────────────┘
515
516 Email
517 ┌─────────────────────────┬────────────────────────────┐
518 │SECURITY_EMAIL_SUB‐ │ Sets the subject for the │
519 │JECT_REGISTER │ confirmation email. │
520 │ │ Defaults to Welcome │
521 ├─────────────────────────┼────────────────────────────┤
522 │SECURITY_EMAIL_SUB‐ │ Sets the subject for the │
523 │JECT_PASSWORDLESS │ passwordless feature. │
524 │ │ Defaults to Login instruc‐ │
525 │ │ tions │
526 ├─────────────────────────┼────────────────────────────┤
527 │SECURITY_EMAIL_SUB‐ │ Sets subject for the pass‐ │
528 │JECT_PASSWORD_NOTICE │ word notice. Defaults to │
529 │ │ Your password has been │
530 │ │ reset │
531 ├─────────────────────────┼────────────────────────────┤
532 │SECURITY_EMAIL_SUB‐ │ Sets the subject for the │
533 │JECT_PASSWORD_RESET │ password reset email. │
534 │ │ Defaults to Password reset │
535 │ │ instructions │
536 ├─────────────────────────┼────────────────────────────┤
537 │SECURITY_EMAIL_SUB‐ │ Sets the subject for the │
538 │JECT_PASS‐ │ password change notice. │
539 │WORD_CHANGE_NOTICE │ Defaults to Your password │
540 │ │ has been changed │
541 └─────────────────────────┴────────────────────────────┘
542
543 │SECURITY_EMAIL_SUB‐ │ Sets the subject for the │
544 │JECT_CONFIRM │ email confirmation mes‐ │
545 │ │ sage. Defaults to Please │
546 │ │ confirm your email │
547 ├─────────────────────────┼────────────────────────────┤
548 │SECURITY_EMAIL_PLAINTEXT │ Sends email as plaintext │
549 │ │ using *.txt template. │
550 │ │ Defaults to True. │
551 ├─────────────────────────┼────────────────────────────┤
552 │SECURITY_EMAIL_HTML │ Sends email as HTML using │
553 │ │ *.html template. Defaults │
554 │ │ to True. │
555 └─────────────────────────┴────────────────────────────┘
556
557 Miscellaneous
558 ┌──────────────────────────┬────────────────────────────┐
559 │SECURITY_USER_IDEN‐ │ Specifies which attributes │
560 │TITY_ATTRIBUTES │ of the user object can be │
561 │ │ used for login. Defaults │
562 │ │ to ['email']. │
563 ├──────────────────────────┼────────────────────────────┤
564 │SECURITY_SEND_REGIS‐ │ Specifies whether regis‐ │
565 │TER_EMAIL │ tration email is sent. │
566 │ │ Defaults to True. │
567 ├──────────────────────────┼────────────────────────────┤
568 │SECURITY_SEND_PASS‐ │ Specifies whether password │
569 │WORD_CHANGE_EMAIL │ change email is sent. │
570 │ │ Defaults to True. │
571 ├──────────────────────────┼────────────────────────────┤
572 │SECURITY_SEND_PASS‐ │ Specifies whether password │
573 │WORD_RESET_EMAIL │ reset email is sent. │
574 │ │ Defaults to True. │
575 ├──────────────────────────┼────────────────────────────┤
576 │SECURITY_SEND_PASS‐ │ Specifies whether password │
577 │WORD_RESET_NOTICE_EMAIL │ reset notice email is │
578 │ │ sent. Defaults to True. │
579 ├──────────────────────────┼────────────────────────────┤
580 │SECURITY_CON‐ │ Specifies the amount of │
581 │FIRM_EMAIL_WITHIN │ time a user has before │
582 │ │ their confirmation link │
583 │ │ expires. Always pluralized │
584 │ │ the time unit for this │
585 │ │ value. Defaults to 5 │
586 │ │ days. │
587 ├──────────────────────────┼────────────────────────────┤
588 │SECURITY_RESET_PASS‐ │ Specifies the amount of │
589 │WORD_WITHIN │ time a user has before │
590 │ │ their password reset link │
591 │ │ expires. Always pluralized │
592 │ │ the time unit for this │
593 │ │ value. Defaults to 5 days. │
594 ├──────────────────────────┼────────────────────────────┤
595 │SECURITY_LOGIN_WITHIN │ Specifies the amount of │
596 │ │ time a user has before a │
597 │ │ login link expires. This │
598 │ │ is only used when the │
599 │ │ passwordless login feature │
600 │ │ is enabled. Always plural‐ │
601 │ │ ized the time unit for │
602 │ │ this value. Defaults to 1 │
603 │ │ days. │
604 └──────────────────────────┴────────────────────────────┘
605
606
607
608
609
610
611 │SECURITY_LOGIN_WITH‐ │ Specifies if a user may │
612 │OUT_CONFIRMATION │ login before confirming │
613 │ │ their email when the value │
614 │ │ of SECURITY_CONFIRMABLE is │
615 │ │ set to True. Defaults to │
616 │ │ False. │
617 ├──────────────────────────┼────────────────────────────┤
618 │SECURITY_CONFIRM_SALT │ Specifies the salt value │
619 │ │ when generating confirma‐ │
620 │ │ tion links/tokens. │
621 │ │ Defaults to confirm-salt. │
622 ├──────────────────────────┼────────────────────────────┤
623 │SECURITY_RESET_SALT │ Specifies the salt value │
624 │ │ when generating password │
625 │ │ reset links/tokens. │
626 │ │ Defaults to reset-salt. │
627 ├──────────────────────────┼────────────────────────────┤
628 │SECURITY_LOGIN_SALT │ Specifies the salt value │
629 │ │ when generating login │
630 │ │ links/tokens. Defaults to │
631 │ │ login-salt. │
632 ├──────────────────────────┼────────────────────────────┤
633 │SECURITY_REMEMBER_SALT │ Specifies the salt value │
634 │ │ when generating remember │
635 │ │ tokens. Remember tokens │
636 │ │ are used instead of user │
637 │ │ ID’s as it is more secure. │
638 │ │ Defaults to remember-salt. │
639 ├──────────────────────────┼────────────────────────────┤
640 │SECURITY_DEFAULT_REMEM‐ │ Specifies the default │
641 │BER_ME │ “remember me” value used │
642 │ │ when logging in a user. │
643 │ │ Defaults to False. │
644 ├──────────────────────────┼────────────────────────────┤
645 │SECURITY_DATETIME_FACTORY │ Specifies the default │
646 │ │ datetime factory. Defaults │
647 │ │ to datetime.datetime.utc‐ │
648 │ │ now. │
649 └──────────────────────────┴────────────────────────────┘
650
651 Messages
652 The following are the messages Flask-Security uses. They are tuples;
653 the first element is the message and the second element is the error
654 level.
655
656 The default messages and error levels can be found in core.py.
657
658 · SECURITY_MSG_ALREADY_CONFIRMED
659
660 · SECURITY_MSG_CONFIRMATION_EXPIRED
661
662 · SECURITY_MSG_CONFIRMATION_REQUEST
663
664 · SECURITY_MSG_CONFIRMATION_REQUIRED
665
666 · SECURITY_MSG_CONFIRM_REGISTRATION
667
668 · SECURITY_MSG_DISABLED_ACCOUNT
669
670 · SECURITY_MSG_EMAIL_ALREADY_ASSOCIATED
671
672 · SECURITY_MSG_EMAIL_CONFIRMED
673
674 · SECURITY_MSG_EMAIL_NOT_PROVIDED
675
676 · SECURITY_MSG_FORGOT_PASSWORD
677
678 · SECURITY_MSG_INVALID_CONFIRMATION_TOKEN
679
680 · SECURITY_MSG_INVALID_EMAIL_ADDRESS
681
682 · SECURITY_MSG_INVALID_LOGIN_TOKEN
683
684 · SECURITY_MSG_INVALID_PASSWORD
685
686 · SECURITY_MSG_INVALID_REDIRECT
687
688 · SECURITY_MSG_INVALID_RESET_PASSWORD_TOKEN
689
690 · SECURITY_MSG_LOGIN
691
692 · SECURITY_MSG_LOGIN_EMAIL_SENT
693
694 · SECURITY_MSG_LOGIN_EXPIRED
695
696 · SECURITY_MSG_PASSWORDLESS_LOGIN_SUCCESSFUL
697
698 · SECURITY_MSG_PASSWORD_CHANGE
699
700 · SECURITY_MSG_PASSWORD_INVALID_LENGTH
701
702 · SECURITY_MSG_PASSWORD_IS_THE_SAME
703
704 · SECURITY_MSG_PASSWORD_MISMATCH
705
706 · SECURITY_MSG_PASSWORD_NOT_PROVIDED
707
708 · SECURITY_MSG_PASSWORD_NOT_SET
709
710 · SECURITY_MSG_PASSWORD_RESET
711
712 · SECURITY_MSG_PASSWORD_RESET_EXPIRED
713
714 · SECURITY_MSG_PASSWORD_RESET_REQUEST
715
716 · SECURITY_MSG_REFRESH
717
718 · SECURITY_MSG_RETYPE_PASSWORD_MISMATCH
719
720 · SECURITY_MSG_UNAUTHORIZED
721
722 · SECURITY_MSG_USER_DOES_NOT_EXIST
723
724 Quick Start
725 · Basic SQLAlchemy Application
726
727 · Basic SQLAlchemy Application with session
728
729 · Basic MongoEngine Application
730
731 · Basic Peewee Application
732
733 · Mail Configuration
734
735 · Proxy Configuration
736
737 Basic SQLAlchemy Application
738 SQLAlchemy Install requirements
739 $ mkvirtualenv <your-app-name>
740 $ pip install flask-security flask-sqlalchemy
741
742 SQLAlchemy Application
743 The following code sample illustrates how to get started as quickly as
744 possible using SQLAlchemy:
745
746 from flask import Flask, render_template
747 from flask_sqlalchemy import SQLAlchemy
748 from flask_security import Security, SQLAlchemyUserDatastore, \
749 UserMixin, RoleMixin, login_required
750
751 # Create app
752 app = Flask(__name__)
753 app.config['DEBUG'] = True
754 app.config['SECRET_KEY'] = 'super-secret'
755 app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
756
757 # Create database connection object
758 db = SQLAlchemy(app)
759
760 # Define models
761 roles_users = db.Table('roles_users',
762 db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
763 db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
764
765 class Role(db.Model, RoleMixin):
766 id = db.Column(db.Integer(), primary_key=True)
767 name = db.Column(db.String(80), unique=True)
768 description = db.Column(db.String(255))
769
770 class User(db.Model, UserMixin):
771 id = db.Column(db.Integer, primary_key=True)
772 email = db.Column(db.String(255), unique=True)
773 password = db.Column(db.String(255))
774 active = db.Column(db.Boolean())
775 confirmed_at = db.Column(db.DateTime())
776 roles = db.relationship('Role', secondary=roles_users,
777 backref=db.backref('users', lazy='dynamic'))
778
779 # Setup Flask-Security
780 user_datastore = SQLAlchemyUserDatastore(db, User, Role)
781 security = Security(app, user_datastore)
782
783 # Create a user to test with
784 @app.before_first_request
785 def create_user():
786 db.create_all()
787 user_datastore.create_user(email='matt@nobien.net', password='password')
788 db.session.commit()
789
790 # Views
791 @app.route('/')
792 @login_required
793 def home():
794 return render_template('index.html')
795
796 if __name__ == '__main__':
797 app.run()
798
799 Basic SQLAlchemy Application with session
800 SQLAlchemy Install requirements
801 $ mkvirtualenv <your-app-name>
802 $ pip install flask-security sqlalchemy
803
804 Also, you can use the extension Flask-SQLAlchemy-Session documentation.
805
806 SQLAlchemy Application
807 The following code sample illustrates how to get started as quickly as
808 possible using SQLAlchemy in a declarative way:
809
810 We are gonna split the application at least in three files: app.py,
811 database.py and models.py. You can also do the models a folder and
812 spread your tables there.
813
814 · app.py
815
816 :: from flask import Flask from flask_security import Security,
817 login_required,
818 SQLAlchemySessionUserDatastore
819
820 from database import db_session, init_db from models import
821 User, Role
822
823 # Create app app = Flask(__name__) app.config[‘DEBUG’] = True
824 app.config[‘SECRET_KEY’] = ‘super-secret’
825
826 # Setup Flask-Security user_datastore = SQLAlchemySessionUser‐
827 Datastore(db_session,
828 User, Role)
829
830 security = Security(app, user_datastore)
831
832 # Create a user to test with @app.before_first_request def cre‐
833 ate_user():
834 init_db() user_datastore.create_user(email=’matt@nobien.net’,
835 password=’password’) db_session.commit()
836
837 # Views @app.route(‘/’) @login_required def home():
838 return render(‘Here you go!’)
839
840 if __name__ == ‘__main__’:
841 app.run()
842
843 · database.py
844
845 :: from sqlalchemy import create_engine from sqlalchemy.orm import
846 scoped_session, sessionmaker from sqlalchemy.ext.declarative
847 import declarative_base
848
849 engine = create_engine(‘sqlite:////tmp/test.db’,
850 convert_unicode=True)
851
852 db_session = scoped_session(sessionmaker(autocommit=False,
853 autoflush=False, bind=engine))
854
855 Base = declarative_base() Base.query = db_session.query_prop‐
856 erty()
857
858 def init_db():
859 # import all modules here that might define models so
860 that # they will be registered properly on the metadata.
861 Otherwise # you will have to import them first before
862 calling init_db() import models Base.metadata.cre‐
863 ate_all(bind=engine)
864
865 · models.py
866
867 :: from database import Base from flask_security import UserMixin,
868 RoleMixin from sqlalchemy import create_engine from
869 sqlalchemy.orm import relationship, backref from sqlalchemy
870 import Boolean, DateTime, Column, Integer,
871 String, ForeignKey
872
873 class RolesUsers(Base):
874 __tablename__ = ‘roles_users’ id = Column(Integer(), pri‐
875 mary_key=True) user_id = Column(‘user_id’, Integer(),
876 ForeignKey(‘user.id’)) role_id = Column(‘role_id’, Inte‐
877 ger(), ForeignKey(‘role.id’))
878
879 class Role(Base, RoleMixin):
880 __tablename__ = ‘role’ id = Column(Integer(), pri‐
881 mary_key=True) name = Column(String(80), unique=True)
882 description = Column(String(255))
883
884 class User(Base, UserMixin):
885 __tablename__ = ‘user’ id = Column(Integer, pri‐
886 mary_key=True) email = Column(String(255), unique=True)
887 username = Column(String(255)) password = Col‐
888 umn(String(255)) last_login_at = Column(DateTime()) cur‐
889 rent_login_at = Column(DateTime()) last_login_ip = Col‐
890 umn(String(100)) current_login_ip = Column(String(100))
891 login_count = Column(Integer) active = Column(Boolean())
892 confirmed_at = Column(DateTime()) roles = relation‐
893 ship(‘Role’, secondary=’roles_users’,
894 backref=backref(‘users’, lazy=’dynamic’))
895
896 Basic MongoEngine Application
897 MongoEngine Install requirements
898 $ mkvirtualenv <your-app-name>
899 $ pip install flask-security flask-mongoengine
900
901 MongoEngine Application
902 The following code sample illustrates how to get started as quickly as
903 possible using MongoEngine:
904
905 from flask import Flask, render_template
906 from flask_mongoengine import MongoEngine
907 from flask_security import Security, MongoEngineUserDatastore, \
908 UserMixin, RoleMixin, login_required
909
910 # Create app
911 app = Flask(__name__)
912 app.config['DEBUG'] = True
913 app.config['SECRET_KEY'] = 'super-secret'
914
915 # MongoDB Config
916 app.config['MONGODB_DB'] = 'mydatabase'
917 app.config['MONGODB_HOST'] = 'localhost'
918 app.config['MONGODB_PORT'] = 27017
919
920 # Create database connection object
921 db = MongoEngine(app)
922
923 class Role(db.Document, RoleMixin):
924 name = db.StringField(max_length=80, unique=True)
925 description = db.StringField(max_length=255)
926
927 class User(db.Document, UserMixin):
928 email = db.StringField(max_length=255)
929 password = db.StringField(max_length=255)
930 active = db.BooleanField(default=True)
931 confirmed_at = db.DateTimeField()
932 roles = db.ListField(db.ReferenceField(Role), default=[])
933
934 # Setup Flask-Security
935 user_datastore = MongoEngineUserDatastore(db, User, Role)
936 security = Security(app, user_datastore)
937
938 # Create a user to test with
939 @app.before_first_request
940 def create_user():
941 user_datastore.create_user(email='matt@nobien.net', password='password')
942
943 # Views
944 @app.route('/')
945 @login_required
946 def home():
947 return render_template('index.html')
948
949 if __name__ == '__main__':
950 app.run()
951
952 Basic Peewee Application
953 Peewee Install requirements
954 $ mkvirtualenv <your-app-name>
955 $ pip install flask-security flask-peewee
956
957 Peewee Application
958 The following code sample illustrates how to get started as quickly as
959 possible using Peewee:
960
961 from flask import Flask, render_template
962 from flask_peewee.db import Database
963 from peewee import *
964 from flask_security import Security, PeeweeUserDatastore, \
965 UserMixin, RoleMixin, login_required
966
967 # Create app
968 app = Flask(__name__)
969 app.config['DEBUG'] = True
970 app.config['SECRET_KEY'] = 'super-secret'
971 app.config['DATABASE'] = {
972 'name': 'example.db',
973 'engine': 'peewee.SqliteDatabase',
974 }
975
976 # Create database connection object
977 db = Database(app)
978
979 class Role(db.Model, RoleMixin):
980 name = CharField(unique=True)
981 description = TextField(null=True)
982
983 class User(db.Model, UserMixin):
984 email = TextField()
985 password = TextField()
986 active = BooleanField(default=True)
987 confirmed_at = DateTimeField(null=True)
988
989 class UserRoles(db.Model):
990 # Because peewee does not come with built-in many-to-many
991 # relationships, we need this intermediary class to link
992 # user to roles.
993 user = ForeignKeyField(User, related_name='roles')
994 role = ForeignKeyField(Role, related_name='users')
995 name = property(lambda self: self.role.name)
996 description = property(lambda self: self.role.description)
997
998 # Setup Flask-Security
999 user_datastore = PeeweeUserDatastore(db, User, Role, UserRoles)
1000 security = Security(app, user_datastore)
1001
1002 # Create a user to test with
1003 @app.before_first_request
1004 def create_user():
1005 for Model in (Role, User, UserRoles):
1006 Model.drop_table(fail_silently=True)
1007 Model.create_table(fail_silently=True)
1008 user_datastore.create_user(email='matt@nobien.net', password='password')
1009
1010 # Views
1011 @app.route('/')
1012 @login_required
1013 def home():
1014 return render_template('index.html')
1015
1016 if __name__ == '__main__':
1017 app.run()
1018
1019 Mail Configuration
1020 Flask-Security integrates with Flask-Mail to handle all email communi‐
1021 cations between user and site, so it’s important to configure
1022 Flask-Mail with your email server details so Flask-Security can talk
1023 with Flask-Mail correctly.
1024
1025 The following code illustrates a basic setup, which could be added to
1026 the basic application code in the previous section:
1027
1028 # At top of file
1029 from flask_mail import Mail
1030
1031 # After 'Create app'
1032 app.config['MAIL_SERVER'] = 'smtp.example.com'
1033 app.config['MAIL_PORT'] = 465
1034 app.config['MAIL_USE_SSL'] = True
1035 app.config['MAIL_USERNAME'] = 'username'
1036 app.config['MAIL_PASSWORD'] = 'password'
1037 mail = Mail(app)
1038
1039 To learn more about the various Flask-Mail settings to configure it to
1040 work with your particular email server configuration, please see the
1041 Flask-Mail documentation.
1042
1043 Proxy Configuration
1044 The user tracking features need an additional configuration in HTTP
1045 proxy environment. The following code illustrates a setup with a single
1046 HTTP proxy in front of the web application:
1047
1048 # At top of file
1049 from werkzeug.config.fixers import ProxyFix
1050
1051 # After 'Create app'
1052 app.wsgi_app = ProxyFix(app.wsgi_app, num_proxies=1)
1053
1054 To learn more about the ProxyFix middleware, please see the Werkzeug
1055 documentation.
1056
1057 Models
1058 Flask-Security assumes you’ll be using libraries such as SQLAlchemy,
1059 MongoEngine, Peewee or PonyORM to define a data model that includes a
1060 User and Role model. The fields on your models must follow a particular
1061 convention depending on the functionality your app requires. Aside from
1062 this, you’re free to add any additional fields to your model(s) if you
1063 want. At the bare minimum your User and Role model should include the
1064 following fields:
1065
1066 User
1067
1068 · id
1069
1070 · email
1071
1072 · password
1073
1074 · active
1075
1076 Role
1077
1078 · id
1079
1080 · name
1081
1082 · description
1083
1084 Additional Functionality
1085 Depending on the application’s configuration, additional fields may
1086 need to be added to your User model.
1087
1088 Confirmable
1089 If you enable account confirmation by setting your application’s SECU‐
1090 RITY_CONFIRMABLE configuration value to True, your User model will
1091 require the following additional field:
1092
1093 · confirmed_at
1094
1095 Trackable
1096 If you enable user tracking by setting your application’s SECU‐
1097 RITY_TRACKABLE configuration value to True, your User model will
1098 require the following additional fields:
1099
1100 · last_login_at
1101
1102 · current_login_at
1103
1104 · last_login_ip
1105
1106 · current_login_ip
1107
1108 · login_count
1109
1110 Custom User Payload
1111 If you want a custom payload after Register or Login an user, define
1112 the method get_security_payload in your User model. The method must
1113 return a serializable object:
1114
1115 class User(db.Model, UserMixin):
1116 id = db.Column(db.Integer, primary_key=True)
1117 email = TextField()
1118 password = TextField()
1119 active = BooleanField(default=True)
1120 confirmed_at = DateTimeField(null=True)
1121 name = db.Column(db.String(80))
1122
1123 # Custom User Payload
1124 def get_security_payload(self):
1125 return {
1126 'id': self.id,
1127 'name': self.name,
1128 'email': self.email
1129 }
1130
1131 Customizing Views
1132 Flask-Security bootstraps your application with various views for han‐
1133 dling its configured features to get you up and running as quickly as
1134 possible. However, you’ll probably want to change the way these views
1135 look to be more in line with your application’s visual design.
1136
1137 Views
1138 Flask-Security is packaged with a default template for each view it
1139 presents to a user. Templates are located within a subfolder named
1140 security. The following is a list of view templates:
1141
1142 · security/forgot_password.html
1143
1144 · security/login_user.html
1145
1146 · security/register_user.html
1147
1148 · security/reset_password.html
1149
1150 · security/change_password.html
1151
1152 · security/send_confirmation.html
1153
1154 · security/send_login.html
1155
1156 Overriding these templates is simple:
1157
1158 1. Create a folder named security within your application’s templates
1159 folder
1160
1161 2. Create a template with the same name for the template you wish to
1162 override
1163
1164 You can also specify custom template file paths in the configuration.
1165
1166 Each template is passed a template context object that includes the
1167 following, including the objects/values that are passed to the template
1168 by the main Flask application context processor:
1169
1170 · <template_name>_form: A form object for the view
1171
1172 · security: The Flask-Security extension object
1173
1174 To add more values to the template context, you can specify a context
1175 processor for all views or a specific view. For example:
1176
1177 security = Security(app, user_datastore)
1178
1179 # This processor is added to all templates
1180 @security.context_processor
1181 def security_context_processor():
1182 return dict(hello="world")
1183
1184 # This processor is added to only the register view
1185 @security.register_context_processor
1186 def security_register_processor():
1187 return dict(something="else")
1188
1189 The following is a list of all the available context processor decora‐
1190 tors:
1191
1192 · context_processor: All views
1193
1194 · forgot_password_context_processor: Forgot password view
1195
1196 · login_context_processor: Login view
1197
1198 · register_context_processor: Register view
1199
1200 · reset_password_context_processor: Reset password view
1201
1202 · change_password_context_processor: Change password view
1203
1204 · send_confirmation_context_processor: Send confirmation view
1205
1206 · send_login_context_processor: Send login view
1207
1208 Forms
1209 All forms can be overridden. For each form used, you can specify a
1210 replacement class. This allows you to add extra fields to the register
1211 form or override validators:
1212
1213 from flask_security.forms import RegisterForm
1214
1215 class ExtendedRegisterForm(RegisterForm):
1216 first_name = StringField('First Name', [Required()])
1217 last_name = StringField('Last Name', [Required()])
1218
1219 security = Security(app, user_datastore,
1220 register_form=ExtendedRegisterForm)
1221
1222 For the register_form and confirm_register_form, each field is passed
1223 to the user model (as kwargs) when a user is created. In the above
1224 case, the first_name and last_name fields are passed directly to the
1225 model, so the model should look like:
1226
1227 class User(db.Model, UserMixin):
1228 id = db.Column(db.Integer, primary_key=True)
1229 email = db.Column(db.String(255), unique=True)
1230 password = db.Column(db.String(255))
1231 first_name = db.Column(db.String(255))
1232 last_name = db.Column(db.String(255))
1233
1234 The following is a list of all the available form overrides:
1235
1236 · login_form: Login form
1237
1238 · confirm_register_form: Confirmable register form
1239
1240 · register_form: Register form
1241
1242 · forgot_password_form: Forgot password form
1243
1244 · reset_password_form: Reset password form
1245
1246 · change_password_form: Change password form
1247
1248 · send_confirmation_form: Send confirmation form
1249
1250 · passwordless_login_form: Passwordless login form
1251
1252 Emails
1253 Flask-Security is also packaged with a default template for each email
1254 that it may send. Templates are located within the subfolder named
1255 security/email. The following is a list of email templates:
1256
1257 · security/email/confirmation_instructions.html
1258
1259 · security/email/confirmation_instructions.txt
1260
1261 · security/email/login_instructions.html
1262
1263 · security/email/login_instructions.txt
1264
1265 · security/email/reset_instructions.html
1266
1267 · security/email/reset_instructions.txt
1268
1269 · security/email/reset_notice.html
1270
1271 · security/email/change_notice.txt
1272
1273 · security/email/change_notice.html
1274
1275 · security/email/reset_notice.txt
1276
1277 · security/email/welcome.html
1278
1279 · security/email/welcome.txt
1280
1281 Overriding these templates is simple:
1282
1283 1. Create a folder named security within your application’s templates
1284 folder
1285
1286 2. Create a folder named email within the security folder
1287
1288 3. Create a template with the same name for the template you wish to
1289 override
1290
1291 Each template is passed a template context object that includes values
1292 for any links that are required in the email. If you require more val‐
1293 ues in the templates, you can specify an email context processor with
1294 the mail_context_processor decorator. For example:
1295
1296 security = Security(app, user_datastore)
1297
1298 # This processor is added to all emails
1299 @security.mail_context_processor
1300 def security_mail_processor():
1301 return dict(hello="world")
1302
1303 Emails with Celery
1304 Sometimes it makes sense to send emails via a task queue, such as
1305 Celery. To delay the sending of emails, you can use the @secu‐
1306 rity.send_mail_task decorator like so:
1307
1308 # Setup the task
1309 @celery.task
1310 def send_security_email(msg):
1311 # Use the Flask-Mail extension instance to send the incoming ``msg`` parameter
1312 # which is an instance of `flask_mail.Message`
1313 mail.send(msg)
1314
1315 @security.send_mail_task
1316 def delay_security_email(msg):
1317 send_security_email.delay(msg)
1318
1319 If factory method is going to be used for initialization, use _Securi‐
1320 tyState object returned by init_app method to initialize Celery tasks
1321 intead of using security.send_mail_task directly like so:
1322
1323 from flask import Flask
1324 from flask_mail import Mail
1325 from flask_security import Security, SQLAlchemyUserDatastore
1326 from celery import Celery
1327
1328 mail = Mail()
1329 security = Security()
1330 celery = Celery()
1331
1332 def create_app(config):
1333 """Initialize Flask instance."""
1334
1335 app = Flask(__name__)
1336 app.config.from_object(config)
1337
1338 @celery.task
1339 def send_flask_mail(msg):
1340 mail.send(msg)
1341
1342 mail.init_app(app)
1343 datastore = SQLAlchemyUserDatastore(db, User, Role)
1344 security_ctx = security.init_app(app, datastore)
1345
1346 # Flexible way for defining custom mail sending task.
1347 @security_ctx.send_mail_task
1348 def delay_flask_security_mail(msg):
1349 send_flask_mail.delay(msg)
1350
1351 # A shortcurt.
1352 security_ctx.send_mail_task(send_flask_mail.delay)
1353
1354 return app
1355
1356 Note that flask_mail.Message may not be serialized as an argument
1357 passed to Celery. The practical way with custom serialization may look
1358 like so:
1359
1360 @celery.task
1361 def send_flask_mail(**kwargs):
1362 mail.send(Message(**kwargs))
1363
1364 @security_ctx.send_mail_task
1365 def delay_flask_security_mail(msg):
1366 send_flask_mail.delay(subject=msg.subject, sender=msg.sender,
1367 recipients=msg.recipients, body=msg.body,
1368 html=msg.html)
1369
1370 API
1371 Core
1372 flask_security.core.current_user
1373 A proxy for the current user.
1374
1375 Protecting Views
1376 User Object Helpers
1377 Datastores
1378 Utils
1379 Signals
1380 See the Flask documentation on signals for information on how to use
1381 these signals in your code.
1382
1383 See the documentation for the signals provided by the Flask-Login and
1384 Flask-Principal extensions. In addition to those signals, Flask-Secu‐
1385 rity sends the following signals.
1386
1387 user_registered
1388 Sent when a user registers on the site. In addition to the app
1389 (which is the sender), it is passed user and confirm_token argu‐
1390 ments.
1391
1392 user_confirmed
1393 Sent when a user is confirmed. In addition to the app (which is
1394 the sender), it is passed a user argument.
1395
1396 confirm_instructions_sent
1397 Sent when a user requests confirmation instructions. In addition
1398 to the app (which is the sender), it is passed a user argument.
1399
1400 login_instructions_sent
1401 Sent when passwordless login is used and user logs in. In addi‐
1402 tion to the app (which is the sender), it is passed user and
1403 login_token arguments.
1404
1405 password_reset
1406 Sent when a user completes a password reset. In addition to the
1407 app (which is the sender), it is passed a user argument.
1408
1409 password_changed
1410 Sent when a user completes a password change. In addition to the
1411 app (which is the sender), it is passed a user argument.
1412
1413 reset_password_instructions_sent
1414 Sent when a user requests a password reset. In addition to the
1415 app (which is the sender), it is passed user and token argu‐
1416 ments.
1417
1418 Flask-Security Changelog
1419 Here you can see the full list of changes between each Flask-Security
1420 release.
1421
1422 Version 3.0.0
1423 Released TBD
1424
1425 · Fixed a bug when user clicking confirmation link after confirmation
1426 and expiration causes confirmation email to resend. (see #556)
1427
1428 · Added support for I18N.
1429
1430 · Added options SECURITY_EMAIL_PLAINTEXT and SECURITY_EMAIL_HTML for
1431 sending respecively plaintext and HTML version of email.
1432
1433 · Fixed validation when missing login information.
1434
1435 · Fixed condition for token extraction from JSON body.
1436
1437 · Better support for universal bdist wheel.
1438
1439 · Added port of CLI using Click configurable using options SECU‐
1440 RITY_CLI_USERS_NAME and SECURITY_CLI_ROLES_NAME.
1441
1442 · Added new configuration option SECURITY_DATETIME_FACTORY which can be
1443 used to force default timezone for newly created datetimes. (see
1444 mattupstate/flask-security#466)
1445
1446 · Better IP tracking if using Flask 0.12.
1447
1448 · Renamed deprecated Flask-WFT base form class.
1449
1450 · Added tests for custom forms configured using app config.
1451
1452 · Added validation and tests for next argument in logout endpoint. (see
1453 #499)
1454
1455 · Bumped minimal required versions of several packages.
1456
1457 · Extended test matric on Travis CI for minimal and released package
1458 versions.
1459
1460 · Added of .editorconfig and forced tests for code style.
1461
1462 · Fixed a security bug when validating a confirmation token, also
1463 checks if the email that the token was created with matches the
1464 user’s current email.
1465
1466 · Replaced token loader with request loader.
1467
1468 · Changed trackable behavior of login_user when IP can not be detected
1469 from a request from ‘untrackable’ to None value.
1470
1471 · Use ProxyFix instead of inspecting X-Forwarded-For header.
1472
1473 · Fix identical problem with app as with datastore.
1474
1475 · Removed always-failing assertion.
1476
1477 · Fixed failure of init_app to set self.datastore.
1478
1479 · Changed to new style flask imports.
1480
1481 · Added proper error code when returning JSON response.
1482
1483 · Changed obsolette Required validator from WTForms to DataRequired.
1484 Bumped Flask-WTF to 0.13.
1485
1486 · Fixed missing SECURITY_SUBDOMAIN in config docs.
1487
1488 · Added cascade delete in PeeweeDatastore.
1489
1490 · Added notes to docs about SECURITY_USER_IDENTITY_ATTRIBUTES.
1491
1492 · Inspect value of SECURITY_UNAUTHORIZED_VIEW.
1493
1494 · Send password reset instructions if an attempt has expired.
1495
1496 · Added “Forgot password?” link to LoginForm description.
1497
1498 · Upgraded passlib, and removed bcrypt version restriction.
1499
1500 · Removed a duplicate line (‘retype_password’: ‘Retype Password’) in
1501 forms.py.
1502
1503 · Various documentation improvement.
1504
1505 Version 1.7.5
1506 Released December 2nd 2015
1507
1508 · Added SECURITY_TOKEN_MAX_AGE configuration setting
1509
1510 · Fixed calls to SQLAlchemyUserDatastore.get_user(None) (this now
1511 returns False instead of raising a TypeError
1512
1513 · Fixed URL generation adding extra slashes in some cases (see GitHub
1514 #343)
1515
1516 · Fixed handling of trackable IP addresses when the X-Forwarded-For
1517 header contains multiple values
1518
1519 · Include WWW-Authenticate headers in @auth_required authentication
1520 checks
1521
1522 · Fixed error when check_token function is used with a json list
1523
1524 · Added support for custom AnonymousUser classes
1525
1526 · Restricted forgot_password endpoint to anonymous users
1527
1528 · Allowed unauthorized callback to be overridden
1529
1530 · Fixed issue where passwords cannot be reset if currently set to None
1531
1532 · Ensured that password reset tokens are invalidated after use
1533
1534 · Updated is_authenticated and is_active functions to support
1535 Flask-Login changes
1536
1537 · Various documentation improvements
1538
1539 Version 1.7.4
1540 Released October 13th 2014
1541
1542 · Fixed a bug related to changing existing passwords from plaintext to
1543 hashed
1544
1545 · Fixed a bug in form validation that did not enforce case insensivitiy
1546
1547 · Fixed a bug with validating redirects
1548
1549 Version 1.7.3
1550 Released June 10th 2014
1551
1552 · Fixed a bug where redirection to SECURITY_POST_LOGIN_VIEW was not
1553 respected
1554
1555 · Fixed string encoding in various places to be friendly to unicode
1556
1557 · Now using werkzeug.security.safe_str_cmp to check tokens
1558
1559 · Removed user information from JSON output on /reset responses
1560
1561 · Added Python 3.4 support
1562
1563 Version 1.7.2
1564 Released May 6th 2014
1565
1566 · Updated IP tracking to check for X-Forwarded-For header
1567
1568 · Fixed a bug regarding the re-hashing of passwords with a new algo‐
1569 rithm
1570
1571 · Fixed a bug regarding the password_changed signal.
1572
1573 Version 1.7.1
1574 Released January 14th 2014
1575
1576 · Fixed a bug where passwords would fail to verify when specifying a
1577 password hash algorithm
1578
1579 Version 1.7.0
1580 Released January 10th 2014
1581
1582 · Python 3.3 support!
1583
1584 · Dependency updates
1585
1586 · Fixed a bug when SECURITY_LOGIN_WITHOUT_CONFIRMATION = True did not
1587 allow users to log in
1588
1589 · Added SECURITY_SEND_PASSWORD_RESET_NOTICE_EMAIL configuraiton option
1590 to optionally send password reset notice emails
1591
1592 · Add documentation for @security.send_mail_task
1593
1594 · Move to request.get_json as request.json is now deprecated in Flask
1595
1596 · Fixed a bug when using AJAX to change a user’s password
1597
1598 · Added documentation for select functions in the flask_security.utils
1599 module
1600
1601 · Fixed a bug in flask_security.forms.NextFormMixin
1602
1603 · Added CHANGE_PASSWORD_TEMPLATE configuration option to optionally
1604 specify a different change password template
1605
1606 · Added the ability to specify addtional fields on the user model to be
1607 used for identifying the user via the USER_IDENTITY_ATTRIBUTES con‐
1608 figuration option
1609
1610 · An error is now shown if a user tries to change their password and
1611 the password is the same as before. The message can be customed with
1612 the SECURITY_MSG_PASSWORD_IS_SAME configuration option
1613
1614 · Fixed a bug in MongoEngineUserDatastore where user model would not be
1615 updated when using the add_role_to_user method
1616
1617 · Added SECURITY_SEND_PASSWORD_CHANGE_EMAIL configuration option to
1618 optionally disable password change email from being sent
1619
1620 · Fixed a bug in the find_or_create_role method of the PeeWee datastore
1621
1622 · Removed pypy tests
1623
1624 · Fixed some tests
1625
1626 · Include CHANGES and LICENSE in MANIFEST.in
1627
1628 · A bit of documentation cleanup
1629
1630 · A bit of code cleanup including removal of unnecessary utcnow call
1631 and simplification of get_max_age method
1632
1633 Version 1.6.9
1634 Released August 20th 2013
1635
1636 · Fix bug in SQLAlchemy datastore’s get_user function
1637
1638 · Fix bug in PeeWee datastore’s remove_role_from_user function
1639
1640 · Fixed import error caused by new Flask-WTF release
1641
1642 Version 1.6.8
1643 Released August 1st 2013
1644
1645 · Fixed bug with case sensitivity of email address during login
1646
1647 · Code cleanup regarding token_callback
1648
1649 · Ignore validation errors in find_user function for MongoEngineUser‐
1650 Datastore
1651
1652 Version 1.6.7
1653 Released July 11th 2013
1654
1655 · Made password length form error message configurable
1656
1657 · Fixed email confirmation bug that prevented logged in users from con‐
1658 firming their email
1659
1660 Version 1.6.6
1661 Released June 28th 2013
1662
1663 · Fixed dependency versions
1664
1665 Version 1.6.5
1666 Released June 20th 2013
1667
1668 · Fixed bug in flask.ext.security.confirmable.generate_confirma‐
1669 tion_link
1670
1671 Version 1.6.4
1672 Released June 18th 2013
1673
1674 · Added SECURITY_DEFAULT_REMEMBER_ME configuration value to unify
1675 behavior between endpoints
1676
1677 · Fixed Flask-Login dependency problem
1678
1679 · Added optional next parameter to registration endpoint, similar to
1680 that of login
1681
1682 Version 1.6.3
1683 Released May 8th 2013
1684
1685 · Fixed bug in regards to imports with latest version of MongoEngine
1686
1687 Version 1.6.2
1688 Released April 4th 2013
1689
1690 · Fixed bug with http basic auth
1691
1692 Version 1.6.1
1693 Released April 3rd 2013
1694
1695 · Fixed bug with signals
1696
1697 Version 1.6.0
1698 Released March 13th 2013
1699
1700 · Added Flask-Pewee support
1701
1702 · Password hashing is now more flexible and can be changed to a differ‐
1703 ent type at will
1704
1705 · Flask-Login messages are configurable
1706
1707 · AJAX requests must now send a CSRF token for security reasons
1708
1709 · Form messages are now configurable
1710
1711 · Forms can now be extended with more fields
1712
1713 · Added change password endpoint
1714
1715 · Added the user to the request context when successfully authenticated
1716 via http basic and token auth
1717
1718 · The Flask-Security blueprint subdomain is now configurable
1719
1720 · Redirects to other domains are now not allowed during requests that
1721 may redirect
1722
1723 · Template paths can be configured
1724
1725 · The welcome/register email can now optionally be sent to the user
1726
1727 · Passwords can now contain non-latin characters
1728
1729 · Fixed a bug when confirming an account but the account has been
1730 deleted
1731
1732 Version 1.5.4
1733 Released January 6th 2013
1734
1735 · Fix bug in forms with csrf_enabled parameter not accounting attempts
1736 to login using JSON data
1737
1738 Version 1.5.3
1739 Released December 23rd 2012
1740
1741 · Change dependency requirement
1742
1743 Version 1.5.2
1744 Released December 11th 2012
1745
1746 · Fix a small bug in flask_security.utils.login_user method
1747
1748 Version 1.5.1
1749 Released November 26th 2012
1750
1751 · Fixed bug with next form variable
1752
1753 · Added better documentation regarding Flask-Mail configuration
1754
1755 · Added ability to configure email subjects
1756
1757 Version 1.5.0
1758 Released October 11th 2012
1759
1760 · Major release. Upgrading from previous versions will require a bit of
1761 work to accomodate API changes. See documentation for a list of new
1762 features and for help on how to upgrade.
1763
1764 Version 1.2.3
1765 Released June 12th 2012
1766
1767 · Fixed a bug in the RoleMixin eq/ne functions
1768
1769 Version 1.2.2
1770 Released April 27th 2012
1771
1772 · Fixed bug where roles_required and roles_accepted did not pass the
1773 next argument to the login view
1774
1775 Version 1.2.1
1776 Released March 28th 2012
1777
1778 · Added optional user model mixin parameter for datastores
1779
1780 · Added CreateRoleCommand to available Flask-Script commands
1781
1782 Version 1.2.0
1783 Released March 12th 2012
1784
1785 · Added configuration option SECURITY_FLASH_MESSAGES which can be set
1786 to a boolean value to specify if Flask-Security should flash messages
1787 or not.
1788
1789 Version 1.1.0
1790 Initial release Flask-Security is written and maintained by Matt Wright
1791 and various contributors:
1792
1793 Development Lead
1794 · Matt Wright <matt+github@nobien.net>
1795
1796 Patches and Suggestions
1797 Alexander Sukharev Alexey Poryadin Andrew J. Camenga Anthony Plunkett
1798 Artem Andreev Catherine Wise Chris Haines Christophe Simonis David
1799 Ignacio Eric Butler Eskil Heyn Olsen Iuri de Silvio Jay Goel Jiri Kun‐
1800 car Joe Esposito Joe Hand Josh Purvis Kostyantyn Leschenko Luca Inv‐
1801 ernizzi Manuel Ebert Martin Maillard Paweł Krześniak Robert Clark
1802 Rodrigue Cloutier Rotem Yaari Srijan Choudhary Tristan Escalada Vadim
1803 Kotov Walt Askew John Paraskevopoulos
1804
1806 Matt Wright
1807
1809 2012, Matt Wright
1810
1811
1812
1813
18143.0.0 Jul 15, 2018 FLASK-SECURITY(1)