1

I am using Flask-Security with custom templates for my login forms. I have my form defined but for whatever reason the form isnt being passed to the template.

Here is the form code

class LoginForm(FlaskForm):
    email = TextField('Email Address', [
            Required(message='Forgot your email address?')])
    password = PasswordField('Password', [
            Required(message='Must provide a password. ;-)')])

Here is the template code

<form method="POST" action="." accept-charset="UTF-8" role="form">
    {{ form.csrf_token }} {{ render_field(form.email, placeholder="Your Email Address", autofocus="") }} {{ render_field(form.password, placeholder="Password") }}
        <div>
            <label>
                        <input type="checkbox" name="remember" value="1"> Remember Me
                    </label>
                        <a role="button" href="">Forgot your password?</a><span class="clearfix"></span>
        </div>
                    <button type="submit" name="submit">Sign in</button>        
</form>

Here is the code for the login

@mod_auth.route('/signin/', methods=['GET', 'POST'])
def signin():
    # If sign in form is submitted
    form = LoginForm(request.form)
    # Verify the sign in form
    if form.validate_on_submit():
        for user in User.objects(email=form.email.data):
            if user and user.password == form.password.data:
                login_user(user)
            if not is_safe_url(next):
                flash('Logging you in')
                return flask.abort(400)
            return redirect(next or ('/')
        elif user:
            flash('Wrong password')
        else:
            flash('could not find username')
    return render_template("security/login_user.html", form=form)

The code works if I remove the line in the config

app.config['SECURITY_LOGIN_URL'] = '/auth/signin/'

But when that line is there it throws this error

Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
 File "/usr/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/lib/python3.6/site-packages/flask_security/decorators.py", line 230, in wrapper
return f(*args, **kwargs)
File "/usr/lib/python3.6/site-packages/flask_security/views.py", line 89, in login
**_ctx('login'))
File "/usr/lib/python3.6/site-packages/flask_security/core.py", line 528, in render_template
return render_template(*args, **kwargs)
File "/usr/lib/python3.6/site-packages/flask/templating.py", line 134, in render_template
context, ctx.app)
File "/usr/lib/python3.6/site-packages/flask/templating.py", line 116, in _render
rv = template.render(context)
File "/usr/lib/python3.6/site-packages/jinja2/asyncsupport.py", line 76, in render
return original_render(self, *args, **kwargs)
File "/usr/lib/python3.6/site-packages/jinja2/environment.py", line 1008, in render
return self.environment.handle_exception(exc_info, True)
File "/usr/lib/python3.6/site-packages/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3.6/site-packages/jinja2/_compat.py", line 37, in reraise
raise value.with_traceback(tb)
File "/home/kenton/Programming/bridal/bridal-website/becomeOne/app/templates/security/login_user.html", line 1, in top-level template code
{% extends "base.html" %} {% block content %}
File "/home/kenton/Programming/bridal/bridal-website/becomeOne/app/templates/base.html", line 1, in top-level template code
{% block doc -%}
File "/home/kenton/Programming/bridal/bridal-website/becomeOne/app/templates/base.html", line 4, in block "doc"
{%- block html %}
File "/home/kenton/Programming/bridal/bridal-website/becomeOne/app/templates/base.html", line 43, in block "html"
{% block body -%}
File "/home/kenton/Programming/bridal/bridal-website/becomeOne/app/templates/base.html", line 48, in block "body"
{% block content -%} {%- endblock content %} {% block scripts %}
File "/home/kenton/Programming/bridal/bridal-website/becomeOne/app/templates/security/login_user.html", line 22, in block "content"
{% endif %} {% endwith %} {% if form.errors %}
File "/usr/lib/python3.6/site-packages/jinja2/environment.py", line 430, in getattr
return getattr(obj, attribute)
jinja2.exceptions.UndefinedError: 'form' is undefined

Any thoughts or help at all would be great! Thanks in advance.

Kenton
  • 69
  • 1
  • 1
  • 8
  • You use Flask-Security, Why do you deal with login yourself? – stamaimer Aug 23 '17 at 15:11
  • 1
    @stamaimer well I saw that security used flask login for logins and I never saw anything on how to do the login so I went to flask login and setup something resembles their documentation. How should I be doing the logins – Kenton Aug 23 '17 at 15:59
  • Have you ever browse the [quick start](https://pythonhosted.org/Flask-Security/quickstart.html) of Flask-Security? – stamaimer Aug 23 '17 at 16:08
  • 1
    @stamaimer Yeah been through the quick start and a lot of the other documentation. There is nothing about how to setup the login thats why I went to flask-logins documentation for that. – Kenton Aug 23 '17 at 16:27

2 Answers2

1

So it seems that you need to pass this through another method to the security variable. I know this is old but might help people. Took me a while to work this one out.

@app.security.login_context_processor
def login_context_processor():
    return dict(form=LoginForm())

You need to look at this part of the docs

Each template is passed a template context object that includes the following, including the objects/values that are passed to the template by the main Flask application context processor:

<template_name>_form: A form object for the view

security: The Flask-Security extension object

To add more values to the template context, you can specify a context processor for all views or a specific view. For example:

security = Security(app, user_datastore)

This processor is added to all templates @security.context_processor def security_context_processor():

return dict(hello="world")

This processor is added to only the register view @security.register_context_processor def

security_register_processor(): return dict(something="else") The following is a list of all the available context processor decorators:

context_processor: All views

forgot_password_context_processor: Forgot password view

login_context_processor: Login view

mf_recovery_codes_context_processor: Setup recovery codes view

mf_recovery_context_processor: Use recovery code view

register_context_processor: Register view

reset_password_context_processor: Reset password view

change_password_context_processor: Change password view

send_confirmation_context_processor: Send confirmation view

send_login_context_processor: Send login view

mail_context_processor: Whenever an email will be sent

tf_select_context_processor: Two factor select view

tf_setup_context_processor: Two factor setup view

tf_token_validation_context_processor: Two factor token validation view

us_signin_context_processor: Unified sign in view

us_setup_context_processor: Unified sign in setup view

wan_register_context_processor: WebAuthn registration view

wan_signin_context_processor: WebAuthn sign in view

wan_verify_context_processor: WebAuthn verify view

MattC03
  • 25
  • 4
0

Jinja2 is throwing the error :

jinja2.exceptions.UndefinedError: 'form' is undefined

The template code above uses form which it doesn't know about.You are not supplying it to the template which uses it. You have to pass the form through for the template which uses it.

0decimal0
  • 3,884
  • 2
  • 24
  • 39