2
respostas

Faça como eu fiz: validando os formulários

Utilizar o CSRF no arquivo jogoteca.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)
app.config.from_pyfile('config.py')

db = SQLAlchemy(app)
csrf = CSRFProtect(app)

from views import *

if __name__ == '__main__':
    app.run(debug=True)

Importar o wtforms no arquivo helpers.py e criar dois formulários.

from wtforms import StringField, SubmitField, PasswordField, validators
class FormularioJogo(FlaskForm):
    nome = StringField('Nome do Jogo',
                       [validators.DataRequired(),
                        validators.Length(min=1, max=50)])
    categoria = StringField('Categoria',
                            [validators.DataRequired(),
                             validators.Length(min=1, max=40)])
    console = StringField('Console',
                          [validators.DataRequired(),
                           validators.Length(min=1, max=20)])
    salvar = SubmitField('Salvar')


class FormularioUsuario(FlaskForm):
    nickname = StringField('Nickname', 
                           [validators.DataRequired(),
                                        validators.Length(min=1, max=8)])
    senha = PasswordField('Senha', 
                          [validators.DataRequired(),
                                    validators.Length(min=1, max=100)])
    login = SubmitField('Login')

Alterar o arquivo views.py

@app.route('/novo')
def novo():
    if 'usuario_logado' not in session or session['usuario_logado'] == None:
        return redirect(url_for('login', proxima=url_for('novo')))
    form = FormularioJogo()
    return render_template('novo.html', titulo='Novo Jogo',
                           form=form)
@app.route('/criar', methods=['POST', ])
def criar():
    form = FormularioJogo(request.form)

    if not form.validate_on_submit():
        return redirect(url_for('novo'))

    nome = form.nome.data
    categoria = form.categoria.data
    console = form.console.data

    jogo = Jogos.query.filter_by(nome=nome).first()

    if jogo:
        flash('Jogo já existente!')
        return redirect(url_for('index'))

    novo_jogo = Jogos(nome=nome, categoria=categoria, console=console)
    db.session.add(novo_jogo)
    db.session.commit()

    arquivo = request.files['arquivo']
    upload_path = app.config['UPLOAD_PATH']
    timestamp = time.time()
    arquivo.save(f'{upload_path}/capa{novo_jogo.id}-{timestamp}.jpg')

    return redirect(url_for('index'))
@app.route('/editar/<int:id>')
def editar(id):
    if 'usuario_logado' not in session or session['usuario_logado'] == None:
        return redirect(url_for('login', proxima=url_for('editar')))
    jogo = Jogos.query.filter_by(id=id).first()
    form = FormularioJogo()
    form.nome.data = jogo.nome
    form.categoria.data = jogo.categoria
    form.console.data = jogo.console
    capa_jogo = recupera_imagem(id)
    return render_template('editar.html', titulo='Editando Jogo', id=id,
                           capa_jogo=capa_jogo, form=form)
@app.route('/atualizar', methods=['POST', ])
def atualizar():
    form = FormularioJogo(request.form)

    if form.validate_on_submit():
        jogo = Jogos.query.filter_by(id=request.form['id']).first()
        jogo.nome = form.nome.data
        jogo.categoria = form.categoria.data
        jogo.console = form.console.data

        db.session.add(jogo)
        db.session.commit()

        arquivo = request.files['arquivo']
        upload_path = app.config['UPLOAD_PATH']
        timestamp = time.time()
        deleta_arquivo(jogo.id)
        arquivo.save(f'{upload_path}/capa{jogo.id}-{timestamp}.jpg')

    return redirect(url_for('index'))
@app.route('/login')
def login():
    proxima = request.args.get('proxima')
    form = FormularioUsuario()
    return render_template('login.html', proxima=proxima, form=form)
@app.route('/autenticar', methods=['POST', ])
def autenticar():
    form = FormularioUsuario(request.form)
    usuario = Usuarios.query.filter_by(nickname=form.nickname.data).first()
    if usuario:
        if form.senha.data == usuario.senha:
            session['usuario_logado'] = usuario.nickname
            flash(usuario.nickname + ' logado com sucesso!')
            proxima_pagina = request.form['proxima']
            return redirect(proxima_pagina)
    else:
        flash('Usuário não logado.')
        return redirect(url_for('login'))
2 respostas

Alterações na página novo.html

<fieldset>
        {{ form.csrf_token() }}
        <div class="form-group">
            {{ form.nome.label(class="form-label") }}
            {{ form.nome(class="form-control") }}
        </div>
        <div class="form-group">
            {{ form.categoria.label(class="form-label") }}
            {{ form.categoria(class="form-control") }}
        </div>
        <div class="form-group">
            {{ form.console.label(class="form-label") }}
            {{ form.console(class="form-control") }}
        </div>
        <div class="form-group">
            {{ form.salvar(class="btn btn-primary") }}
            <a class="btn btn-danger" href="{{ url_for('index') }}">Voltar</a>
        </div>
    </fieldset>

Página editar.html

<fieldset>
        <input type="hidden" name="id" value="{{ id }}">
        {{ form.csrf_token() }}
        <div class="form-group">
            {{ form.nome.label(class="form-label") }}
            {{ form.nome(class="form-control") }}
        </div>
        <div class="form-group">
            {{ form.categoria.label(class="form-label") }}
            {{ form.categoria(class="form-control") }}
        </div>
        <div class="form-group">
            {{ form.console.label(class="form-label") }}
            {{ form.console(class="form-control") }}
        </div>
        <div class="form-group">
            {{ form.salvar(class="btn btn-primary") }}
            <a class="btn btn-danger" href="{{ url_for('index') }}">Voltar</a>
        </div>
    </fieldset>

E na página login.html

<h1>Faça seu login</h1>
    <form method="POST" action="{{ url_for('autenticar') }}">
        <input type="hidden" name="proxima" value="{{ proxima or url_for('index') }}">
        {{ form.csrf_token() }}
        <div class="form-group">
            {{ form.nickname.label(class="form-label") }}
            {{ form.nickname(class="form-control") }}
        </div>
        <div class="form-group">
            {{ form.senha.label(class="form-label") }}
            {{ form.senha(class="form-control") }}
        </div>
        <div class="form-group">
            {{ form.login(class="btn btn-primary") }}
        </div>
    </form>
    <a class="btn btn-danger" href="{{ url_for('index') }}">Voltar</a>

Adaptando ao padrão Cross-Site Request Forgery ou CSRF, que é uma "vulnerabilidade na segurança da web que possibilita a um indivíduo mal intencionado se passar por um usuário inocente".

Oi, Anderson, tudo bem?

Obrigado por compartilhar no fórum e contribuir com a comunidade!

Continue mergulhando em tecnologia e se tiver dúvidas, conte com o fórum.

Abraços e bons estudos!