Marconcilio Souza
Marconcilio Souza

Reputation: 177

Erro A secret key is required to use CSRF. Python/Flask

I am getting the error A secret key is required to use CSRF., In my production environment, when I am in the development environment my application normally.

The message is direct and says what is needed, except that I already have a SECRET_KEY defined.

def __create_env(env_file: str):
    if not os.path.isfile(env_file):
        context = "FLASK_ENV=production" + "\n"
        context += "ENV=production" + "\n"
        context += "SERVER_NAME=127.0.0.1:8080" + "\n"
        context += "DEBUG=False" + "\n"
        context += "TESTING=False" + "\n"
        context += "PROPAGATE_EXCEPTIONS=False" + "\n"
        context += "SECRET_KEY=my SECRET KEY"+ "\n"
        context += "JWT_SECRET_KEY=....." + "\n"
        with open(env_file, "w") as reader:
            reader.write(context)

My __init__.py looks like this:

from flask import (Flask, jsonify, make_response, request)
from flask_jwt_extended import JWTManager
from flask_minify import minify
from flask_wtf import CSRFProtect

from src import (autenticacao, config, util)
from src.views import (vw_estatistica)

app = Flask(__name__)
csrf = CSRFProtect(app)
app.url_map.strict_slashes = False
app.jinja_env.lstrip_blocks = True
app.jinja_env.trim_blocks = True
app.jinja_env.cache = {}
app.config['SESSION_COOKIE_DOMAIN'] = '...com.br'
app.config['SESSION_COOKIE_SECURE'] = True

cache.init_app(app=app, config={
    "CACHE_TYPE": "simple",
    "CACHE_DEFAULT_TIMEOUT": 300
})

minify(app=app, html=True, js=False, cssless=False)

jwt = JWTManager(app)

vw_estatistica.configure(app)

csrf.init_app(app)

The error I'm getting is:

Traceback (most recent call last): File "/var/www/.../principal/src/views/vw_estatistica.py", line 25, in loginestatistica form = estatistica_model.LoginEstatisticaForm() File "/usr/local/lib/python3.8/site-packages/wtforms/form.py", line 208, in call return type.call(cls, *args, **kwargs) File "/usr/local/lib/python3.8/site-packages/flask_wtf/form.py", line 87, in init super(FlaskForm, self).init(formdata=formdata, **kwargs) File "/usr/local/lib/python3.8/site-packages/wtforms/form.py", line 274, in init self.process(formdata, obj, data=data, **kwargs) File "/usr/local/lib/python3.8/site-packages/wtforms/form.py", line 131, in process field.process(formdata) File "/usr/local/lib/python3.8/site-packages/wtforms/csrf/core.py", line 43, in process self.current_token = self.csrf_impl.generate_csrf_token(self) File "/usr/local/lib/python3.8/site-packages/flask_wtf/csrf.py", line 139, in generate_csrf_token return generate_csrf( File "/usr/local/lib/python3.8/site-packages/flask_wtf/csrf.py", line 33, in generate_csrf secret_key = _get_config( File "/usr/local/lib/python3.8/site-packages/flask_wtf/csrf.py", line 128, in _get_config raise RuntimeError(message) RuntimeError: A secret key is required to use CSRF.

The vw_estatistica.py ", line 25, in loginestatistica form = estatistica_model.LoginEstatisticaForm () is as follows.

import json
import traceback

import flask
from flask import Blueprint, jsonify, render_template, redirect, abort, url_for, flash, request
from flask_restful import Api, Resource

from datetime import timedelta, datetime

from src import util, config
from src.models import (log_model, estatistica_model, menu_model)

mod: Blueprint = Blueprint('vw_estatisitca', __name__, template_folder='templates', static_folder='static')


def configure(app):
    api = Api(mod)
    api.add_resource(ObterTopoEstatistica, '/obterTopoEstatistica', '/obterTopoEstatistica/<string:pagina>')
    app.register_blueprint(mod)


@mod.route("/estatistica/login", methods=["GET", "POST"])
def loginestatistica():
    try:
        form = estatistica_model.LoginEstatisticaForm() # line 25

        if request.method == 'POST' and form.validate():
            senha_cript = util.encrypt(form.password.data, config.CHAVE_CRIPTOGRAFIA)

            usuario_estatistica = estatistica_model.get_usuario_estatistica(form.login.data, senha_cript)

            if usuario_estatistica is not None:
                response = flask.make_response(redirect('https://estatistica....com.br'))
                data_expiracao = (datetime.now() + timedelta(days=1))
                id_usuario = util.encrypt(str(usuario_estatistica.id), config.CHAVE_CRIPTOGRAFIA)

                json_usuario_estatistica = json.dumps({'IdUsuario': id_usuario,
                                                       'NomeUsuario': usuario_estatistica.Usuario,
                                                       'DataUltimoAcesso': usuario_estatistica.UltimoAcesso}
                                                      , indent=4, sort_keys=True, default=str)

                response.set_cookie(value=json_usuario_estatistica,
                                    key='estatistica',
                                    max_age=None,
                                    expires=data_expiracao,
                                    path='/',
                                    domain='....com.br',
                                    secure=True,
                                    httponly=False,
                                    samesite='Lax')

                return response

            else:
                flash("Credênciais incorretas", "danger")
                return redirect(url_for(".loginestatistica"))

        menus: list = menu_model.get_menu(request.host_url)
        return render_template("login-estatistica.html",
                               form=form,
                               menus=menus
                               )

    except Exception as error:
        log_model.Salvar('Site www', 'vw_estatistica.py', f'{traceback.format_exc()}', 'estatistica',
                         log_model.Severidade.High)
        abort(502, description=error)
    finally:
        pass

And my HTML page looks like this.

{% extends "layout.html" %}

{%- block dataLayer -%}
{{ dataLayer | safe }}
{%- endblock -%}


{% block content %}
<div class="container-fluid">
    <br />
    <form  action=" {{url_for('.loginestatistica')}}" method="POST">
        {{ form.csrf_token }}
        <div class="row justify-content-center">
            <div class="col-md-4">
                <div class="modal-content">
                    <div class="modal-header text-center">
                        <h1 class=" text-primary text-block h2 font-weight-bold mb-0">Kalunga - Estatística</h1>
                    </div>
                    <div class="modal-body">
                        <div class="input-group mb-3">
                            <div class="input-group-prepend">
                                <span class="input-group-text font-weight-bold"><i
                                        class="fas fa-user mr-1"></i>Login</span>
                            </div>
                            {{ form.login(class_="form-control") }}
                        </div>
                        <div class="input-group mb-3">
                            <div class="input-group-prepend">
                                <span class="input-group-text font-weight-bold"><i
                                        class="fas fa-key mr-1"></i>Senha</span>
                            </div>
                            {{ form.password(class_="form-control") }}
                        </div>
                        <div class="input-group mb-12">
                            <div class="col-md-4">
                                <button type="submit" class="btn btn-primary btn-lg">Login</button>
                            </div>
                            <div class="col-md-6 text-center">
                                <a href="{{url_for('.recuperaracessoestatistica')}}">Recupera acesso</a>
                            </div>
                        </div>
                        <div class="input-group mb-12">
                            {% include 'partials/notification.html' %}
                            {% include 'partials/form-erros.html' %}
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </form>
</div>
<br />
{% endblock %}

I've seen some issues related to the error like this, but I couldn't find the problem, I also tried to follow the steps in the documentation and it didn't work.

Upvotes: 0

Views: 2803

Answers (1)

4xy
4xy

Reputation: 3662

Define the secret_key like

app = Flask(__name__)
app.secret_key = settings.SECRET_KEY

or

app.config['SECRET_KEY'] = settings.SECRET_KEY

Look for details here https://flask.palletsprojects.com/en/1.1.x/config

You should load environment for flask app manually as specified here https://flask.palletsprojects.com/en/1.1.x/api/#configuration

Upvotes: 2

Related Questions