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
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             ┌─────────────────────────────┬────────────────────────────┐
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. │
200             │                             │ Defaults to True.          │
201             └─────────────────────────────┴────────────────────────────┘
202
203SECURITY_I18N_DOMAIN         │ Specifies   the  name  for │
204             │                             │ domain 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_PASS‐               │ Specifies       additional │
246WORD_HASH_OPTIONS            │ options  to  be  passed to │
247             │                             │ the hashing method.        │
248             ├─────────────────────────────┼────────────────────────────┤
249SECURITY_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             ├─────────────────────────────┼────────────────────────────┤
256SECURITY_TOKEN_AUTHENTICA‐   │ Specifies the query string │
257TION_KEY                     │ parameter   to  read  when │
258             │                             │ using  token   authentica‐ │
259             │                             │ tion.      Defaults     to │
260             │                             │ auth_token.                │
261             ├─────────────────────────────┼────────────────────────────┤
262SECURITY_TOKEN_AUTHENTICA‐   │ Specifies  the HTTP header │
263TION_HEADER                  │ to read when  using  token │
264             │                             │ authentication.   Defaults │
265             │                             │ to Authentication-Token.   │
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             ├─────────────────────────────┼────────────────────────────┤
277SECU‐                        │ Specifies   the    default │
278RITY_DEFAULT_HTTP_AUTH_REALM │ authentication  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 │
296              │                           │ reset  URL.  Defaults   to │
297              │                           │ /reset.                    │
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_CON‐              │ Specifies the view to  re‐ │
322FIRM_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
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       SECU‐ 
347              │                           │ RITY_POST_LOGIN_VIEW.      │
348              │                           │ Defaults to 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                   SECU‐ 
359              │                           │ RITY_POST_LOGIN_VIEW.      │
360              │                           │ Defaults to 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 │
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               ┌─────────────────────────┬────────────────────────────┐
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 │
409               │                         │ login  page.  Defaults  to │
410               │                         │ security/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 │
439               │                         │ login   instructions  page │
440               │                         │ for  passwordless  logins. │
441               │                         │ Defaults      to     secu‐ 
442               │                         │ rity/send_login.html.      │
443               └─────────────────────────┴────────────────────────────┘
444
445   Feature Flags
446                ┌──────────────────────┬────────────────────────────┐
447SECURITY_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                ├──────────────────────┼────────────────────────────┤
463SECURITY_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
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. │
482                │                      │ Defaults 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. │
504                │                      │ Defaults 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. │
520               │                         │ Defaults to Welcome        
521               ├─────────────────────────┼────────────────────────────┤
522SECURITY_EMAIL_SUB‐      │ Sets  the  subject for the │
523JECT_PASSWORDLESS        │ passwordless      feature. │
524               │                         │ Defaults 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 
530               │                         │ reset                      
531               ├─────────────────────────┼────────────────────────────┤
532SECURITY_EMAIL_SUB‐      │ Sets  the  subject for the │
533JECT_PASSWORD_RESET      │ password   reset    email. │
534               │                         │ Defaults to Password reset 
535               │                         │ instructions               
536               ├─────────────────────────┼────────────────────────────┤
537SECURITY_EMAIL_SUB‐      │ Sets the subject  for  the │
538JECT_PASS‐               │ password   change  notice. │
539WORD_CHANGE_NOTICE       │ 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. │
550               │                         │ Defaults 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_IDEN‐       │ Specifies which attributes │
560TITY_ATTRIBUTES           │ 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. │
566              │                          │ Defaults to True.          │
567              ├──────────────────────────┼────────────────────────────┤
568SECURITY_SEND_PASS‐       │ Specifies whether password │
569WORD_CHANGE_EMAIL         │ change  email   is   sent. │
570              │                          │ Defaults to True.          │
571              ├──────────────────────────┼────────────────────────────┤
572SECURITY_SEND_PASS‐       │ Specifies whether password │
573WORD_RESET_EMAIL          │ reset   email   is   sent. │
574              │                          │ Defaults to True.          │
575              ├──────────────────────────┼────────────────────────────┤
576SECURITY_SEND_PASS‐       │ Specifies whether password │
577WORD_RESET_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. │
621              │                          │ Defaults to confirm-salt.  │
622              ├──────────────────────────┼────────────────────────────┤
623SECURITY_RESET_SALT       │ Specifies  the  salt value │
624              │                          │ when  generating  password │
625              │                          │ reset        links/tokens. │
626              │                          │ Defaults 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 │
641BER_ME                    │ “remember me”  value  used │
642              │                          │ when  logging  in  a user. │
643              │                          │ Defaults 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
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

AUTHOR

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