Answers: <p>I found the solution!!!</p>
  
  <p>Views Flask-Security is packaged with a default template for each view it presents to a user. Templates are located within a sub-folder named security. The following is a list of view templates:</p>
  
  <pre><code>security/forgot_password.html
  security/login_user.html
  security/register_user.html
  security/reset_password.html
  security/change_password.html
  security/send_confirmation.html
  security/send_login.html
  </code></pre>
  
  <p>Overriding these templates is simple:</p>
  
  <ul>
  <li>Create a folder named security within your application’s templates folder</li>
  <li>Create a template with the same name for the template you wish to override</li>
  </ul>
  
Answers: CC BY-SA 3.0
Answers: 2018-03-26T08:50:40.940Z
Answers: 2018-03-26T20:30:40.087Z
Answers: 2018-03-26T20:30:40.087Z
Answers: alex
Body: <p>I have an issue with my app, since I was adding the feature "users roles" I am getting a strange page content on login page looks like default login page instead of my custom login page and I cannot explain why is happening because I did not change the urls and when I am removing the "users roles code" is working perfect. Could you explain how is possible?</p>
  
  <p>This is the code what is creating the issue:</p>
  
  <pre><code>import os
  import base64
  from io import BytesIO
  from flask import Flask, render_template, request, redirect, url_for, flash, session, \
      abort
  from werkzeug.security import generate_password_hash, check_password_hash
  from flask_sqlalchemy import SQLAlchemy
  from flask_login import LoginManager, UserMixin, login_user, logout_user, \
      current_user
  from flask_bootstrap import Bootstrap
  from flask_wtf import FlaskForm
  from wtforms import StringField, PasswordField, SubmitField, SelectField
  from wtforms.validators import Required, Length, EqualTo
  import onetimepass
  import pyqrcode
  from datetime import datetime, date, time, timedelta
  from sqlalchemy import Table, Column, Integer, ForeignKey
  from sqlalchemy.orm import relationship
  from sqlalchemy.ext.declarative import declarative_base
  from flask_security import Security, SQLAlchemyUserDatastore, \
      UserMixin, RoleMixin, login_required
  
  # create application instance
  app = Flask(__name__)
  app.config.from_object('config')
  
  # initialize extensions
  bootstrap = Bootstrap(app)
  db = SQLAlchemy(app)
  lm = LoginManager(app)
  Base = declarative_base()
  
  # Define models
  roles_users = db.Table('roles_users',
          db.Column('users_id', db.Integer(), db.ForeignKey('users.id')),
          db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
  
  class Role(db.Model, RoleMixin):
      id = db.Column(db.Integer(), primary_key=True)
      name = db.Column(db.String(80), unique=True)
      description = db.Column(db.String(255))
  
  class User(UserMixin, db.Model):
      """User model."""
      __tablename__ = 'users'
      id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True)
      username = db.Column(db.String(64), unique=True, index=True)
      password_hash = db.Column(db.String(128))
      otp_secret = db.Column(db.String(16))
      access = db.Column(db.String(16))
      roles = db.relationship('Role', secondary=roles_users,
                              backref=db.backref('users', lazy='dynamic'))
  
      def __init__(self, **kwargs):
          super(User, self).__init__(**kwargs)
          if self.otp_secret is None:
              # generate a random secret
              self.otp_secret = base64.b32encode(os.urandom(10)).decode('utf-8')
  
      @property
      def password(self):
          raise AttributeError('password is not a readable attribute')
  
      @password.setter
      def password(self, password):
          self.password_hash = generate_password_hash(password)
  
      def verify_password(self, password):
          return check_password_hash(self.password_hash, password)
  
      def get_totp_uri(self):
          return 'otpauth://totp/2FA-Demo:{0}?secret={1}&amp;issuer=2FA-Demo' \
              .format(self.username, self.otp_secret)
  
      def verify_totp(self, token):
          return onetimepass.valid_totp(token, self.otp_secret)
  
  ################################################################################
  user_datastore = SQLAlchemyUserDatastore(db, User, Role)
  security = Security(app, user_datastore)
  ###############################################################################
  
  @lm.user_loader
  def load_user(user_id):
      """User loader callback for Flask-Login."""
      return User.query.get(int(user_id))
  
  class RegisterForm(FlaskForm):
      """Registration form."""
      access = SelectField(validators=[Required()],
              choices=[("dm", "demo"),
              ("dm2", "demo2")])
      username = StringField('Username', validators=[Required(), Length(1, 9)])
      password = PasswordField('Password', validators=[Required(), Length(4, 4)])
      password_again = PasswordField('Password again',
                                     validators=[Required(), EqualTo('password')])
      submit = SubmitField('Register')
  
  
  class LoginForm(FlaskForm):
      """Login form."""
      username = StringField('Username', validators=[Required(), Length(1, 9)])
      password = PasswordField('Password', validators=[Required(), Length(4, 4)])
      token = PasswordField('Token', validators=[Required(), Length(6, 6)])
      submit = SubmitField('Login')
  
  @app.route('/')
  def index():
      return render_template('index.html')
  
  
  @app.route('/register', methods=['GET', 'POST'])
  def register():
      """User registration route."""
      if current_user.is_authenticated:
          # if user is logged in we get out of here
          return redirect(url_for('index'))
      form = RegisterForm()
      if form.validate_on_submit():
          user = User.query.filter_by(username=form.username.data).first()
          if user is not None:
              flash('Username already exists.')
              return redirect(url_for('register'))
          # add new user to the database
          user = User(username=form.username.data, password=form.password.data, access=form.access.data)
          db.session.add(user)
          db.session.commit()
  
          # redirect to the two-factor auth page, passing username in session
          session['username'] = user.username
          return redirect(url_for('two_factor_setup'))
      return render_template('auth/register.html', form=form)
  
  
  @app.route('/twofactor')
  def two_factor_setup():
      if 'username' not in session:
          return redirect(url_for('index'))
      user = User.query.filter_by(username=session['username']).first()
      if user is None:
          return redirect(url_for('index'))
      # since this page contains the sensitive qrcode, make sure the browser
      # does not cache it
      return render_template('auth/2fa.html'), 200, {
          'Cache-Control': 'no-cache, no-store, must-revalidate',
          'Pragma': 'no-cache',
          'Expires': '0'}
  
  
  @app.route('/qrcode')
  def qrcode():
      if 'username' not in session:
          abort(404)
      user = User.query.filter_by(username=session['username']).first()
      if user is None:
          abort(404)
  
      # for added security, remove username from session
      del session['username']
  
      # render qrcode for FreeTOTP
      url = pyqrcode.create(user.get_totp_uri())
      stream = BytesIO()
      url.svg(stream, scale=3)
      return stream.getvalue(), 200, {
          'Content-Type': 'image/svg+xml',
          'Cache-Control': 'no-cache, no-store, must-revalidate',
          'Pragma': 'no-cache',
          'Expires': '0'}
  
  
  @app.route('/login', methods=['GET', 'POST'])
  def login():
      """User login route."""
      if current_user.is_authenticated:
          # if user is logged in we get out of here
          return redirect(url_for('index'))
      form = LoginForm()
      if form.validate_on_submit():
          user = User.query.filter_by(username=form.username.data).first()
          if user is None or not user.verify_password(form.password.data) or \
                  not user.verify_totp(form.token.data):
              flash('Invalid username, password or token.')
              return redirect(url_for('login'))
  
          # log user in
          login_user(user)
          flash('You are now logged in!')
          return redirect(url_for('cm_e_11a'))
      return render_template('auth/login.html', form=form)
  
  
  @app.route('/logout')
  def logout():
      """User logout route."""
      logout_user()
      return redirect(url_for('index'))
  </code></pre>
  
  <p>And this is the Login page what is returning </p>
  
  <p><a href="https://i.sstatic.net/t0ONV.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/t0ONV.png" alt="pic"></a></p>
  
  <p>instead of mine what should contain username, password &amp; pin</p>
  
  <p>And the login page has this source code:</p>
  
  <pre><code>&lt;h1&gt;Login&lt;/h1&gt;
  &lt;form action="/login" method="POST" name="login_user_form"&gt;
    &lt;input id="next" name="next" type="hidden" value=""&gt;
  &lt;input id="csrf_token" name="csrf_token" type="hidden" value="IjEyNWY4ZjliNmIxZTJjNmM3YmM4YzFlM2U0NWZlYjJlMDEzYThiNWEi.DZnvqw.key_C7NmtQogY7CSpb14sfVDUOQ"&gt;
  
    &lt;p&gt;
      &lt;label for="email"&gt;Email Address&lt;/label&gt; &lt;input id="email" name="email" type="text" value=""&gt;
  
    &lt;/p&gt;
  
  
    &lt;p&gt;
      &lt;label for="password"&gt;Password&lt;/label&gt; &lt;input id="password" name="password" type="password" value=""&gt;
  
    &lt;/p&gt;
  
  
    &lt;p&gt;
      &lt;label for="remember"&gt;Remember Me&lt;/label&gt; &lt;input id="remember" name="remember" type="checkbox" value="y"&gt;
  
    &lt;/p&gt;
  
  
    &lt;p&gt;&lt;input id="next" name="next" type="hidden" value=""&gt;&lt;/p&gt;
  
  
    &lt;p&gt;&lt;input id="submit" name="submit" type="submit" value="Login"&gt;&lt;/p&gt;
  
  &lt;/form&gt;
  </code></pre>
  
Tags: <python>
Title: Why flask is returning a default login page instead mine, custom one
UserDisplayName: alex
ThreadText: # Why flask is returning a default login page instead mine, custom one
  
  (Asked by: username_0 on 2018-03-26)
  
  I have an issue with my app, since I was adding the feature "users roles" I am getting a strange page content on login page looks like default login page instead of my custom login page and I cannot explain why is happening because I did not change the urls and when I am removing the "users roles code" is working perfect. Could you explain how is possible?
  
  This is the code what is creating the issue:
  
  ```
  import os
  import base64
  from io import BytesIO
  from flask import Flask, render_template, request, redirect, url_for, flash, session, \
      abort
  from werkzeug.security import generate_password_hash, check_password_hash
  from flask_sqlalchemy import SQLAlchemy
  from flask_login import LoginManager, UserMixin, login_user, logout_user, \
      current_user
  from flask_bootstrap import Bootstrap
  from flask_wtf import FlaskForm
  from wtforms import StringField, PasswordField, SubmitField, SelectField
  from wtforms.validators import Required, Length, EqualTo
  import onetimepass
  import pyqrcode
  from datetime import datetime, date, time, timedelta
  from sqlalchemy import Table, Column, Integer, ForeignKey
  from sqlalchemy.orm import relationship
  from sqlalchemy.ext.declarative import declarative_base
  from flask_security import Security, SQLAlchemyUserDatastore, \
      UserMixin, RoleMixin, login_required
  
  # create application instance
  app = Flask(__name__)
  app.config.from_object('config')
  
  # initialize extensions
  bootstrap = Bootstrap(app)
  db = SQLAlchemy(app)
  lm = LoginManager(app)
  Base = declarative_base()
  
  # Define models
  roles_users = db.Table('roles_users',
          db.Column('users_id', db.Integer(), db.ForeignKey('users.id')),
          db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
  
  class Role(db.Model, RoleMixin):
      id = db.Column(db.Integer(), primary_key=True)
      name = db.Column(db.String(80), unique=True)
      description = db.Column(db.String(255))
  
  class User(UserMixin, db.Model):
      """User model."""
      __tablename__ = 'users'
      id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True)
      username = db.Column(db.String(64), unique=True, index=True)
      password_hash = db.Column(db.String(128))
      otp_secret = db.Column(db.String(16))
      access = db.Column(db.String(16))
      roles = db.relationship('Role', secondary=roles_users,
                              backref=db.backref('users', lazy='dynamic'))
  
      def __init__(self, **kwargs):
          super(User, self).__init__(**kwargs)
          if self.otp_secret is None:
              # generate a random secret
              self.otp_secret = base64.b32encode(os.urandom(10)).decode('utf-8')
  
      @property
      def password(self):
          raise AttributeError('password is not a readable attribute')
  
      @password.setter
      def password(self, password):
          self.password_hash = generate_password_hash(password)
  
      def verify_password(self, password):
          return check_password_hash(self.password_hash, password)
  
      def get_totp_uri(self):
          return 'otpauth://totp/2FA-Demo:{0}?secret={1}&issuer=2FA-Demo' \
              .format(self.username, self.otp_secret)
  
      def verify_totp(self, token):
          return onetimepass.valid_totp(token, self.otp_secret)
  
  ################################################################################
  user_datastore = SQLAlchemyUserDatastore(db, User, Role)
  security = Security(app, user_datastore)
  ###############################################################################
  
  @lm.user_loader
  def load_user(user_id):
      """User loader callback for Flask-Login."""
      return User.query.get(int(user_id))
  
  class RegisterForm(FlaskForm):
      """Registration form."""
      access = SelectField(validators=[Required()],
              choices=[("dm", "demo"),
              ("dm2", "demo2")])
      username = StringField('Username', validators=[Required(), Length(1, 9)])
      password = PasswordField('Password', validators=[Required(), Length(4, 4)])
      password_again = PasswordField('Password again',
                                     validators=[Required(), EqualTo('password')])
      submit = SubmitField('Register')
  
  class LoginForm(FlaskForm):
      """Login form."""
      username = StringField('Username', validators=[Required(), Length(1, 9)])
      password = PasswordField('Password', validators=[Required(), Length(4, 4)])
      token = PasswordField('Token', validators=[Required(), Length(6, 6)])
      submit = SubmitField('Login')
  
  @app.route('/')
  def index():
      return render_template('index.html')
  
  @app.route('/register', methods=['GET', 'POST'])
  def register():
      """User registration route."""
      if current_user.is_authenticated:
          # if user is logged in we get out of here
          return redirect(url_for('index'))
      form = RegisterForm()
      if form.validate_on_submit():
          user = User.query.filter_by(username=form.username.data).first()
          if user is not None:
              flash('Username already exists.')
              return redirect(url_for('register'))
          # add new user to the database
          user = User(username=form.username.data, password=form.password.data, access=form.access.data)
          db.session.add(user)
          db.session.commit()
  
          # redirect to the two-factor auth page, passing username in session
          session['username'] = user.username
          return redirect(url_for('two_factor_setup'))
      return render_template('auth/register.html', form=form)
  
  @app.route('/twofactor')
  def two_factor_setup():
      if 'username' not in session:
          return redirect(url_for('index'))
      user = User.query.filter_by(username=session['username']).first()
      if user is None:
          return redirect(url_for('index'))
      # since this page contains the sensitive qrcode, make sure the browser
      # does not cache it
      return render_template('auth/2fa.html'), 200, {
          'Cache-Control': 'no-cache, no-store, must-revalidate',
          'Pragma': 'no-cache',
          'Expires': '0'}
  
  @app.route('/qrcode')
  def qrcode():
      if 'username' not in session:
          abort(404)
      user = User.query.filter_by(username=session['username']).first()
      if user is None:
          abort(404)
  
      # for added security, remove username from session
      del session['username']
  
      # render qrcode for FreeTOTP
      url = pyqrcode.create(user.get_totp_uri())
      stream = BytesIO()
      url.svg(stream, scale=3)
      return stream.getvalue(), 200, {
          'Content-Type': 'image/svg+xml',
          'Cache-Control': 'no-cache, no-store, must-revalidate',
          'Pragma': 'no-cache',
          'Expires': '0'}
  
  @app.route('/login', methods=['GET', 'POST'])
  def login():
      """User login route."""
      if current_user.is_authenticated:
          # if user is logged in we get out of here
          return redirect(url_for('index'))
      form = LoginForm()
      if form.validate_on_submit():
          user = User.query.filter_by(username=form.username.data).first()
          if user is None or not user.verify_password(form.password.data) or \
                  not user.verify_totp(form.token.data):
              flash('Invalid username, password or token.')
              return redirect(url_for('login'))
  
          # log user in
          login_user(user)
          flash('You are now logged in!')
          return redirect(url_for('cm_e_11a'))
      return render_template('auth/login.html', form=form)
  
  @app.route('/logout')
  def logout():
      """User logout route."""
      logout_user()
      return redirect(url_for('index'))
  
  ```
  
  And this is the Login page what is returning
  
  [![pic](https://i.sstatic.net/t0ONV.png)](https://i.sstatic.net/t0ONV.png)
  
  instead of mine what should contain username, password & pin
  
  And the login page has this source code:
  
  ```
  <h1>Login</h1>
  <form action="/login" method="POST" name="login_user_form">
    <input id="next" name="next" type="hidden" value="">
  <input id="csrf_token" name="csrf_token" type="hidden" value="IjEyNWY4ZjliNmIxZTJjNmM3YmM4YzFlM2U0NWZlYjJlMDEzYThiNWEi.DZnvqw.key_C7NmtQogY7CSpb14sfVDUOQ">
  
    <p>
      <label for="email">Email Address</label> <input id="email" name="email" type="text" value="">
  
    </p>
  
    <p>
      <label for="password">Password</label> <input id="password" name="password" type="password" value="">
  
    </p>
  
    <p>
      <label for="remember">Remember Me</label> <input id="remember" name="remember" type="checkbox" value="y">
  
    </p>
  
    <p><input id="next" name="next" type="hidden" value=""></p>
  
    <p><input id="submit" name="submit" type="submit" value="Login"></p>
  
  </form>
  
  ```
  
  **Tags:** python
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2018-03-26. Score: 1 | Accepted answer
  
  I found the solution!!!
  
  Views Flask-Security is packaged with a default template for each view it presents to a user. Templates are located within a sub-folder named security. The following is a list of view templates:
  
  ```
  security/forgot_password.html
  security/login_user.html
  security/register_user.html
  security/reset_password.html
  security/change_password.html
  security/send_confirmation.html
  security/send_login.html
  
  ```
  
  Overriding these templates is simple:
  
  * Create a folder named security within your application’s templates folder
  * Create a template with the same name for the template you wish to override
  
  
  ---
  
  