Python Forum

Full Version: Flask session behaves erratically
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
My Flask Session behaves in an unpredictable manner. I'm using the same Flask Session settings I did in my previous project, and yet this time it's completely chaotic.

I log in, save the value in session["user_type"] to track the account privileges, and then after going to another page with @admin_required wrapper sometimes it goes on in a normal way, and sometimes it redirects me back to the login page with an error message that I don't have an admin level.

I've read somewhere that it may happen with "SECRET_KEY" missing, but as you can see, I have it in my code, so have no idea where the issue might be.

app = Flask(__name__)
app.config["SECRET_KEY"] = "abcdef"

# Session settings
app.config["SESSION_TYPE"] = "filesystem"
app.config["SESSION_FILE_DIR"] = "session"
app.config["SESSION_USE_SIGNER"] = True
app.config["SESSION_PERMANENT"] = True
app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(hours=16)
Session(app)

def admin_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if session.get("user_type") != "admin":
            flash(Markup("<strong>Error: admin level required</strong>" +
                         "<br>If you have an admin account, please sign in."),
                  "danger")
            return redirect("/sign-in")
        return f(*args, **kwargs)
    return decorated_function


@app.route("/admin/article/add")
@admin_required
def article_add():
    return render_template("article_add.html")


@app.route("/admin/dashboard")
@admin_required
def dashboard():
    return render_template("dashboard.html")

@app.route("/sign-in", methods=["GET", "POST"])
def sign_in():
    if request.method == "POST":
        # Clear the session for a new user to sign in
        session.clear()
        # Get the sign in form data
        # . . .
        # Add the session data about the signed in user
        session["user_id"] = users[0]["user_id"]
        session["username"] = users[0]["username"]
        session["user_type"] = users[0]["user_type"]
        if session["user_type"] == "admin":
            return redirect("/admin/dashboard")
        return redirect("/")
    return render_template("sign-in.html")
are you setting Flask environment variables in a startup script (like .bashrc_profile)?
No I am setting it all inside my app.py. As I've said, I did set it up exactly the same way it was done in the previous project. But now it's completely random. Sometimes I am trying to follow the link and get 5+ times in a row redirected to the sign-in page, and other times just go through without any issues. Even may stop and restart the the server and staying signed in.

I'd understand if the issue would be constant. But I can't figure what could cause it sometimes to work and other times not. Like something is wiping session["user_type"] value.
I setup my system to look like: https://github.com/miguelgrinberg/flasky
there is a video for this as well: https://www.youtube.com/watch?v=UXqiVe6h3lA

I'm not suggesting you go this route, but since I started using it, I have not had any problems.
Sorry I can't help you more, perhaps someone else will pick up here.
Thanks for the links, but it's way too different from the way I usually set my projects. And I didn't have any issues with it before either, so I think the issue is somewhere in this project itself, I just can't figure out what is causing it. Anyway, thanks for trying to help. Was trying to find a solution at Stack Overflow also, there nobody gave any suggestions at all...
An update on the matter... I've added few more lines to track what is happening to the @admin_required decorator and all such views, like dashboard() and article_add():

print("admin_required")
if not session.get("user_id") is None:
    print("session['user_id'] = " + str(session.get("user_id")))
if not session.get("username") is None:
    print("session['username'] = " + session.get("username", "unknown username"))
if not session.get("user_type") is None:
    print("session['user_type'] = " + session.get("user_type", "unknown user type"))
Restarted the server and did few redirects here and there, starting from sign_in(). First few times I've got in the terminal logs correct prints with all 3 session keys values: user_id, username and user_type. Then after one more redirect I've only got admin_required printed, because all 3 keys were now gone for no reason.