S
S
sergey199408082017-04-12 11:21:30
Flask
sergey19940808, 2017-04-12 11:21:30

Flask, how to solve registration confirmation issue?

I would like to confirm my registration via email. The application is written in Python using the Flask framework.
User model:

class User(db.Model):
    confirmed = db.Column(db.Boolean)


Here the confirmed field is responsible for confirmation of registration.
There are also three functions for:
# генерации зашифрованного токена
def generate_confirmation_token(email):
    serializer = URLSafeTimedSerializer(SECRET_KEY)
    return serializer.dumps(email, salt=SECURITY_PASSWORD_SALT)

# возвращение токена
def confirm_token(token, expiration=3600):
    serializer = URLSafeTimedSerializer(SECRET_KEY)
    try:
        email = serializer.loads(
            token,
            salt=SECURITY_PASSWORD_SALT,
            max_age=expiration
        )
    except:
        return False
    return email


# функции отправка письма
def send_email(to, subject, template):
    msg = Message(
        subject,
        recipients=[to],
        html=template,
        sender=FLASK_MAIL_SENDER
    )
    mail.send(msg)


There are also views:

# вьюшка регистрации
@app.route('/register', methods=['GET', 'POST'])
def register():
    title = 'Регистрация'
    form = RegisterForm()
    if form.validate_on_submit():
        user_add = User(form.nickname.data,
                        form.email.data, form.password.data, confirmed=False)
        db.session.add(user_add)
        db.session.commit()
        subject = 'Подтвердите свой email'
        token = generate_confirmation_token(user.email)
        confirm_url = url_for('user.confirm_email', token=token, external=True)
        html = render_template('email/confirm', confirm_url=confirm_url)
        send_email(user.email, subject, html)
        login_user(user_add)
        flash(u'Письмо с подтверждением отправлено по электронной почте', 'success')
        return redirect(url_for('user', nickname=g.user.nickname))
    return render_template('user/register.html', title=title, form=form)


# вьюшка подтверждения регистрации
@app.route('/confirm/<token>')
def confirm_email(token):
    global email
    try:
        email = confirm_token(token)
    except:
        flash('Ссылка на проверку email неверная или устарела.', 'danger')
        abort(404)
    user = User.query.filter_by(email=email).first_or_404()
    if user.confirmed:
        flash('Учётная запись уже подтверждена. Пожалуйста введите логин.', 'success')
    else:
        user.confirmed = True
        db.session.add(user)
        db.session.commit()
    return redirect(url_for('index'))


As a result, a new user is registered, and the debugger returns an error:
AttributeError: 'function' object has no attribute 'email'


How can I get rid of her? What's my mistake?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Konovalov, 2017-04-12
@akonovalov

1) Global variables are bad, they can be very confusing when there is more code. OOP is everything.
2) Generic exceptions are bad, a typo/bug in the confirm_token function will always lead to the same result as the regular False output. This also applies to the confirm_token function - a typo in the serializer and you always have False.
3) Read the tracebacks carefully, please. Find out what is the function you are looking for the email attribute from.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question