1FLASK-SECURITY(1)               Flask-Security               FLASK-SECURITY(1)
2
3
4

NAME

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

CONTENTS

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 au‐
66       tomatically 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 al‐
83       gorithm.  You should always use an hashing algorithm in your production
84       environment. You may also specify to use HMAC with  a  configured  salt
85       value  in  addition  to the algorithm chosen. Bear in mind passlib does
86       not assume which algorithm you will choose and may  require  additional
87       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 to‐
101       ken  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 ex‐
115       pired 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  re‐
148       member  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              ┌───────────────────────────┬────────────────────────────┐
173SECURITY_BLUEPRINT_NAME    │ Specifies the name for the │
174              │                           │ Flask-Security  blueprint. │
175              │                           │ Defaults to security.      │
176              ├───────────────────────────┼────────────────────────────┤
177SECURITY_CLI_USERS_NAME    │ Specifies the name for the │
178              │                           │ command   managing  users. │
179              │                           │ Disable by setting  False. │
180              │                           │ Defaults to users.         │
181              ├───────────────────────────┼────────────────────────────┤
182SECURITY_CLI_ROLES_NAME    │ Specifies the name for the │
183              │                           │ command  managing   roles. │
184              │                           │ Disable  by setting False. │
185              │                           │ Defaults to roles.         │
186              ├───────────────────────────┼────────────────────────────┤
187SECURITY_URL_PREFIX        │ Specifies the  URL  prefix │
188              │                           │ for   the   Flask-Security │
189              │                           │ blueprint.   Defaults   to │
190              │                           │ None.                      │
191              ├───────────────────────────┼────────────────────────────┤
192SECURITY_SUBDOMAIN         │ Specifies   the  subdomain │
193              │                           │ for   the   Flask-Security │
194              │                           │ blueprint.   Defaults   to │
195              │                           │ None.                      │
196              ├───────────────────────────┼────────────────────────────┤
197SECURITY_FLASH_MESSAGES    │ Specifies whether  or  not │
198              │                           │ to  flash  messages during │
199              │                           │ security procedures.   De‐ │
200              │                           │ faults to True.            │
201              └───────────────────────────┴────────────────────────────┘
202
203SECURITY_I18N_DOMAIN       │ Specifies the name for do‐ │
204              │                           │ main  used  for   transla‐ │
205              │                           │ tions.      Defaults    to │
206              │                           │ flask_security.            │
207              ├───────────────────────────┼────────────────────────────┤
208SECURITY_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              ├───────────────────────────┼────────────────────────────┤
217SECURITY_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              ├───────────────────────────┼────────────────────────────┤
224SECURITY_PASSWORD_SIN‐     │ Specifies  that  passwords │
225GLE_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              ├───────────────────────────┼────────────────────────────┤
235SECURITY_HASHING_SCHEMES   │ List  of  algorithms  used │
236              │                           │ for  creating and validat‐ │
237              │                           │ ing tokens.   Defaults  to │
238              │                           │ sha256_crypt.              │
239              ├───────────────────────────┼────────────────────────────┤
240SECURITY_DEPRECATED_HASH‐  │ List of  deprecated  algo‐ │
241ING_SCHEMES                │ rithms  used  for creating │
242              │                           │ and   validating   tokens. │
243              │                           │ Defaults to hex_md5.       │
244              ├───────────────────────────┼────────────────────────────┤
245SECURITY_PASSWORD_HASH_OP‐ │ Specifies  additional  op‐ │
246TIONS                      │ tions  to be passed to the │
247              │                           │ hashing method.            │
248              ├───────────────────────────┼────────────────────────────┤
249SECURITY_EMAIL_SENDER      │ Specifies  the  email  ad‐ │
250              │                           │ dress  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              ├───────────────────────────┼────────────────────────────┤
256SECURITY_TOKEN_AUTHENTICA‐ │ Specifies the query string │
257TION_KEY                   │ parameter to read when us‐ │
258              │                           │ ing token  authentication. │
259              │                           │ Defaults to auth_token.    │
260              ├───────────────────────────┼────────────────────────────┤
261SECURITY_TOKEN_AUTHENTICA‐ │ Specifies the HTTP  header │
262TION_HEADER                │ to  read  when using token │
263              │                           │ authentication.   Defaults │
264              │                           │ to Authentication-Token.   │
265              └───────────────────────────┴────────────────────────────┘
266
267
268
269
270
271SECURITY_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              ├───────────────────────────┼────────────────────────────┤
277SECURITY_DE‐               │ Specifies the default  au‐ │
278FAULT_HTTP_AUTH_REALM      │ thentication   realm  when │
279              │                           │ using  basic  HTTP   auth. │
280              │                           │ Defaults to Login Required 
281              └───────────────────────────┴────────────────────────────┘
282
283   URLs and Views
284              ┌───────────────────────────┬────────────────────────────┐
285SECURITY_LOGIN_URL         │ Specifies  the  login URL. │
286              │                           │ Defaults to /login.        │
287              ├───────────────────────────┼────────────────────────────┤
288SECURITY_LOGOUT_URL        │ Specifies the logout  URL. │
289              │                           │ Defaults to /logout.       │
290              ├───────────────────────────┼────────────────────────────┤
291SECURITY_REGISTER_URL      │ Specifies   the   register │
292              │                           │ URL. Defaults  to  /regis‐ 
293              │                           │ ter.                       │
294              ├───────────────────────────┼────────────────────────────┤
295SECURITY_RESET_URL         │ Specifies the password re‐ │
296              │                           │ set URL. Defaults to  /re‐ 
297              │                           │ set.                       │
298              ├───────────────────────────┼────────────────────────────┤
299SECURITY_CHANGE_URL        │ Specifies   the   password │
300              │                           │ change  URL.  Defaults  to │
301              │                           │ /change.                   │
302              ├───────────────────────────┼────────────────────────────┤
303SECURITY_CONFIRM_URL       │ Specifies  the  email con‐ │
304              │                           │ firmation URL. Defaults to │
305              │                           │ /confirm.                  │
306              ├───────────────────────────┼────────────────────────────┤
307SECURITY_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              ├───────────────────────────┼────────────────────────────┤
314SECURITY_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              ├───────────────────────────┼────────────────────────────┤
321SECURITY_CONFIRM_ER‐       │ Specifies the view to  re‐ │
322ROR_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  de‐ │
328              │                           │ fault  view  to  resend  a │
329              │                           │ confirmation   link.   De‐ │
330              │                           │ faults to None.            │
331              └───────────────────────────┴────────────────────────────┘
332
333
334
335
336
337
338
339SECURITY_POST_REGIS‐       │ Specifies the view to  re‐ │
340TER_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 SECURITY_POST_LO‐ 
347              │                           │ GIN_VIEW.   Defaults    to │
348              │                           │ None.                      │
349              ├───────────────────────────┼────────────────────────────┤
350SECURITY_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       SECURITY_POST_LO‐ 
359              │                           │ GIN_VIEW.   Defaults    to │
360              │                           │ None.                      │
361              ├───────────────────────────┼────────────────────────────┤
362SECURITY_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              ├───────────────────────────┼────────────────────────────┤
373SECURITY_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              ├───────────────────────────┼────────────────────────────┤
384SECURITY_UNAUTHORIZED_VIEW │ Specifies  the view to re‐ │
385              │                           │ direct to if  a  user  at‐ │
386              │                           │ tempts    to    access   a │
387              │                           │ URL/endpoint that they  do │
388              │                           │ not have permission to ac‐ │
389              │                           │ cess.  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               ┌─────────────────────────┬────────────────────────────┐
398SECURITY_FORGOT_PASS‐    │ Specifies  the path to the │
399WORD_TEMPLATE            │ template  for  the  forgot │
400               │                         │ password page. Defaults to │
401               │                         │ security/forgot_pass‐      
402               │                         │ word.html.                 │
403               └─────────────────────────┴────────────────────────────┘
404
405
406
407SECURITY_LOGIN_USER_TEM‐ │ Specifies the path to  the │
408PLATE                    │ template  for the user lo‐ │
409               │                         │ gin page. Defaults to  se‐ 
410               │                         │ curity/login_user.html.    │
411               ├─────────────────────────┼────────────────────────────┤
412SECURITY_REGIS‐          │ Specifies the path to  the │
413TER_USER_TEMPLATE        │ template for the user reg‐ │
414               │                         │ istration  page.  Defaults │
415               │                         │ to         security/regis‐ 
416               │                         │ ter_user.html.             │
417               ├─────────────────────────┼────────────────────────────┤
418SECURITY_RESET_PASS‐     │ Specifies  the path to the │
419WORD_TEMPLATE            │ template  for  the   reset │
420               │                         │ password page. Defaults to │
421               │                         │ security/reset_pass‐       
422               │                         │ word.html.                 │
423               ├─────────────────────────┼────────────────────────────┤
424SECURITY_CHANGE_PASS‐    │ Specifies the path to  the │
425WORD_TEMPLATE            │ template  for  the  change │
426               │                         │ password page. Defaults to │
427               │                         │ security/change_pass‐      
428               │                         │ word.html.                 │
429               ├─────────────────────────┼────────────────────────────┤
430SECURITY_SEND_CONFIRMA‐  │ Specifies  the path to the │
431TION_TEMPLATE            │ template  for  the  resend │
432               │                         │ confirmation  instructions │
433               │                         │ page.  Defaults  to  secu‐ 
434               │                         │ rity/send_confirma‐        
435               │                         │ tion.html.                 │
436               ├─────────────────────────┼────────────────────────────┤
437SECURITY_SEND_LOGIN_TEM‐ │ Specifies  the path to the │
438PLATE                    │ template for the send  lo‐ │
439               │                         │ gin  instructions page for │
440               │                         │ passwordless  logins.  De‐ │
441               │                         │ faults       to      secu‐ 
442               │                         │ rity/send_login.html.      │
443               └─────────────────────────┴────────────────────────────┘
444
445   Feature Flags
446                ┌──────────────────────┬────────────────────────────┐
447SECURITY_CONFIRMABLE  │ Specifies if users are re‐ │
448                │                      │ quired  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   in‐ │
456                │                      │ structions.  The  URL  for │
457                │                      │ this endpoint is specified │
458                │                      │ by    the    SECURITY_CON‐ 
459                │                      │ FIRM_URL configuration op‐ │
460                │                      │ tion.  Defaults to False.  │
461                ├──────────────────────┼────────────────────────────┤
462SECURITY_REGISTERABLE │ Specifies  if  Flask-Secu‐ │
463                │                      │ rity should create a  user │
464                │                      │ registration endpoint. The │
465                │                      │ URL for this  endpoint  is │
466                │                      │ specified   by  the  SECU‐ 
467                │                      │ RITY_REGISTER_URL configu‐ │
468                │                      │ ration option. Defaults to │
469                │                      │ False.                     │
470                └──────────────────────┴────────────────────────────┘
471
472
473
474
475SECURITY_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.  De‐ │
482                │                      │ faults to False.           │
483                ├──────────────────────┼────────────────────────────┤
484SECURITY_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                ├──────────────────────┼────────────────────────────┤
494SECURITY_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.  De‐ │
504                │                      │ faults to False.           │
505                ├──────────────────────┼────────────────────────────┤
506SECURITY_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               ┌─────────────────────────┬────────────────────────────┐
518SECURITY_EMAIL_SUB‐      │ Sets  the  subject for the │
519JECT_REGISTER            │ confirmation  email.   De‐ │
520               │                         │ faults to Welcome          
521               ├─────────────────────────┼────────────────────────────┤
522SECURITY_EMAIL_SUB‐      │ Sets the subject  for  the │
523JECT_PASSWORDLESS        │ passwordless  feature. De‐ │
524               │                         │ faults to  Login  instruc‐ 
525               │                         │ tions                      
526               ├─────────────────────────┼────────────────────────────┤
527SECURITY_EMAIL_SUB‐      │ Sets subject for the pass‐ │
528JECT_PASSWORD_NOTICE     │ word  notice.  Defaults to │
529               │                         │ Your password has been re‐ 
530               │                         │ set                        
531               ├─────────────────────────┼────────────────────────────┤
532SECURITY_EMAIL_SUB‐      │ Sets the subject  for  the │
533JECT_PASSWORD_RESET      │ password  reset email. De‐ │
534               │                         │ faults to  Password  reset 
535               │                         │ instructions               
536               ├─────────────────────────┼────────────────────────────┤
537SECURITY_EMAIL_SUB‐      │ Sets  the  subject for the │
538JECT_PASSWORD_CHANGE_NO‐ │ password  change   notice. │
539TICE                     │ Defaults  to Your password 
540               │                         │ has been changed           
541               └─────────────────────────┴────────────────────────────┘
542
543SECURITY_EMAIL_SUB‐      │ Sets  the  subject for the │
544JECT_CONFIRM             │ email  confirmation   mes‐ │
545               │                         │ sage.  Defaults  to Please 
546               │                         │ confirm your email         
547               ├─────────────────────────┼────────────────────────────┤
548SECURITY_EMAIL_PLAINTEXT │ Sends email  as  plaintext │
549               │                         │ using  *.txt template. De‐ │
550               │                         │ faults to True.            │
551               ├─────────────────────────┼────────────────────────────┤
552SECURITY_EMAIL_HTML      │ Sends email as HTML  using │
553               │                         │ *.html  template. Defaults │
554               │                         │ to True.                   │
555               └─────────────────────────┴────────────────────────────┘
556
557   Miscellaneous
558              ┌───────────────────────────┬────────────────────────────┐
559SECURITY_USER_IDENTITY_AT‐ │ Specifies which attributes │
560TRIBUTES                   │ of the user object can  be │
561              │                           │ used  for login.  Defaults │
562              │                           │ to ['email'].              │
563              ├───────────────────────────┼────────────────────────────┤
564SECURITY_SEND_REGIS‐       │ Specifies  whether  regis‐ │
565TER_EMAIL                  │ tration email is sent. De‐ │
566              │                           │ faults to True.            │
567              ├───────────────────────────┼────────────────────────────┤
568SECURITY_SEND_PASS‐        │ Specifies whether password │
569WORD_CHANGE_EMAIL          │ change  email is sent. De‐ │
570              │                           │ faults to True.            │
571              ├───────────────────────────┼────────────────────────────┤
572SECURITY_SEND_PASSWORD_RE‐ │ Specifies whether password │
573SET_EMAIL                  │ reset email is  sent.  De‐ │
574              │                           │ faults to True.            │
575              ├───────────────────────────┼────────────────────────────┤
576SECURITY_SEND_PASSWORD_RE‐ │ Specifies whether password │
577SET_NOTICE_EMAIL           │ reset   notice   email  is │
578              │                           │ sent. Defaults to True.    │
579              ├───────────────────────────┼────────────────────────────┤
580SECURITY_CON‐              │ Specifies  the  amount  of │
581FIRM_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              ├───────────────────────────┼────────────────────────────┤
588SECURITY_RESET_PASS‐       │ Specifies  the  amount  of │
589WORD_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              ├───────────────────────────┼────────────────────────────┤
595SECURITY_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
611SECURITY_LOGIN_WITH‐       │ Specifies if  a  user  may │
612OUT_CONFIRMATION           │ login   before  confirming │
613              │                           │ their email when the value │
614              │                           │ of SECURITY_CONFIRMABLE is │
615              │                           │ set to True.  Defaults  to │
616              │                           │ False.                     │
617              ├───────────────────────────┼────────────────────────────┤
618SECURITY_CONFIRM_SALT      │ Specifies  the  salt value │
619              │                           │ when generating  confirma‐ │
620              │                           │ tion   links/tokens.   De‐ │
621              │                           │ faults to confirm-salt.    │
622              ├───────────────────────────┼────────────────────────────┤
623SECURITY_RESET_SALT        │ Specifies the  salt  value │
624              │                           │ when  generating  password │
625              │                           │ reset  links/tokens.   De‐ │
626              │                           │ faults to reset-salt.      │
627              ├───────────────────────────┼────────────────────────────┤
628SECURITY_LOGIN_SALT        │ Specifies  the  salt value │
629              │                           │ when   generating    login │
630              │                           │ links/tokens.  Defaults to │
631              │                           │ login-salt.                │
632              ├───────────────────────────┼────────────────────────────┤
633SECURITY_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              ├───────────────────────────┼────────────────────────────┤
640SECURITY_DEFAULT_REMEM‐    │ Specifies the default “re‐ │
641BER_ME                     │ member me” value used when │
642              │                           │ logging  in  a  user.  De‐ │
643              │                           │ faults to False.           │
644              ├───────────────────────────┼────────────────────────────┤
645SECURITY_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
658SECURITY_MSG_ALREADY_CONFIRMED
659
660SECURITY_MSG_CONFIRMATION_EXPIRED
661
662SECURITY_MSG_CONFIRMATION_REQUEST
663
664SECURITY_MSG_CONFIRMATION_REQUIRED
665
666SECURITY_MSG_CONFIRM_REGISTRATION
667
668SECURITY_MSG_DISABLED_ACCOUNT
669
670SECURITY_MSG_EMAIL_ALREADY_ASSOCIATED
671
672SECURITY_MSG_EMAIL_CONFIRMED
673
674SECURITY_MSG_EMAIL_NOT_PROVIDED
675
676SECURITY_MSG_FORGOT_PASSWORD
677
678SECURITY_MSG_INVALID_CONFIRMATION_TOKEN
679
680SECURITY_MSG_INVALID_EMAIL_ADDRESS
681
682SECURITY_MSG_INVALID_LOGIN_TOKEN
683
684SECURITY_MSG_INVALID_PASSWORD
685
686SECURITY_MSG_INVALID_REDIRECT
687
688SECURITY_MSG_INVALID_RESET_PASSWORD_TOKEN
689
690SECURITY_MSG_LOGIN
691
692SECURITY_MSG_LOGIN_EMAIL_SENT
693
694SECURITY_MSG_LOGIN_EXPIRED
695
696SECURITY_MSG_PASSWORDLESS_LOGIN_SUCCESSFUL
697
698SECURITY_MSG_PASSWORD_CHANGE
699
700SECURITY_MSG_PASSWORD_INVALID_LENGTH
701
702SECURITY_MSG_PASSWORD_IS_THE_SAME
703
704SECURITY_MSG_PASSWORD_MISMATCH
705
706SECURITY_MSG_PASSWORD_NOT_PROVIDED
707
708SECURITY_MSG_PASSWORD_NOT_SET
709
710SECURITY_MSG_PASSWORD_RESET
711
712SECURITY_MSG_PASSWORD_RESET_EXPIRED
713
714SECURITY_MSG_PASSWORD_RESET_REQUEST
715
716SECURITY_MSG_REFRESH
717
718SECURITY_MSG_RETYPE_PASSWORD_MISMATCH
719
720SECURITY_MSG_UNAUTHORIZED
721
722SECURITY_MSG_USER_DOES_NOT_EXIST
723
724   Quick Start
725Basic SQLAlchemy Application
726
727Basic SQLAlchemy Application with session
728
729Basic MongoEngine Application
730
731Basic Peewee Application
732
733Mail Configuration
734
735Proxy 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, lo‐
817              gin_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 im‐
847              port 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 im‐
870              port 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) de‐
882                     scription = 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
1068id
1069
1070email
1071
1072password
1073
1074active
1075
1076       Role
1077
1078id
1079
1080name
1081
1082description
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  re‐
1091       quire the following additional field:
1092
1093confirmed_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  re‐
1098       quire the following additional fields:
1099
1100last_login_at
1101
1102current_login_at
1103
1104last_login_ip
1105
1106current_login_ip
1107
1108login_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 re‐
1113       turn 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 se‐
1140       curity. The following is a list of view templates:
1141
1142security/forgot_password.html
1143
1144security/login_user.html
1145
1146security/register_user.html
1147
1148security/reset_password.html
1149
1150security/change_password.html
1151
1152security/send_confirmation.html
1153
1154security/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
1172security: 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
1192context_processor: All views
1193
1194forgot_password_context_processor: Forgot password view
1195
1196login_context_processor: Login view
1197
1198register_context_processor: Register view
1199
1200reset_password_context_processor: Reset password view
1201
1202change_password_context_processor: Change password view
1203
1204send_confirmation_context_processor: Send confirmation view
1205
1206send_login_context_processor: Send login view
1207
1208   Forms
1209       All forms can be overridden. For each form used, you can specify a  re‐
1210       placement  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
1236login_form: Login form
1237
1238confirm_register_form: Confirmable register form
1239
1240register_form: Register form
1241
1242forgot_password_form: Forgot password form
1243
1244reset_password_form: Reset password form
1245
1246change_password_form: Change password form
1247
1248send_confirmation_form: Send confirmation form
1249
1250passwordless_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  se‐
1255       curity/email.  The following is a list of email templates:
1256
1257security/email/confirmation_instructions.html
1258
1259security/email/confirmation_instructions.txt
1260
1261security/email/login_instructions.html
1262
1263security/email/login_instructions.txt
1264
1265security/email/reset_instructions.html
1266
1267security/email/reset_instructions.txt
1268
1269security/email/reset_notice.html
1270
1271security/email/change_notice.txt
1272
1273security/email/change_notice.html
1274
1275security/email/reset_notice.txt
1276
1277security/email/welcome.html
1278
1279security/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 lo‐
1403              gin_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  re‐
1511         turns 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 Flask-Lo‐
1535         gin 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 re‐
1553         spected
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 op‐
1618         tionally 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 be‐
1675         havior 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 Ig‐
1799       nacio Eric Butler Eskil Heyn Olsen Iuri de Silvio Jay Goel Jiri  Kuncar
1800       Joe  Esposito Joe Hand Josh Purvis Kostyantyn Leschenko Luca Invernizzi
1801       Manuel Ebert Martin Maillard  Paweł  Krześniak  Robert  Clark  Rodrigue
1802       Cloutier Rotem Yaari Srijan Choudhary Tristan Escalada Vadim Kotov Walt
1803       Askew John Paraskevopoulos
1804

AUTHOR

1806       Matt Wright
1807
1809       2021, Matt Wright
1810
1811
1812
1813
18143.0.0                            Jan 27, 2021                FLASK-SECURITY(1)
Impressum