0

I'm currently storing session["username"] in my auth module and then trying to access it from my project module from y backend app, specifically from the home endpoint. Problem is session["username"] returns None from the project module

I've tried different app configurations, ChatGPT gave me recommendations and even created a simpler project that had the session functionality working without issues, I replicated the structure but still the same issue.

I did research and supposedly the frontend app shouldn't be an issue, since regardless of what happens in the front (React), the session at the back should remain the same.

app.py

from dotenv import load_dotenv
from flask import Flask
from flask_cors import CORS
from flask_session import Session
from models import db

load_dotenv('.env', override=True)

app = Flask(__name__)
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SECRET_KEY'] = 'verysafekey'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
Session(app)
CORS(app, supports_credentials=True, origins=["http://localhost:3000"])
db.init_app(app)

from routes.auth import auth_bp
from routes.project import project_bp
from routes.jira import jira_bp
# Register blueprints
app.register_blueprint(auth_bp)
app.register_blueprint(project_bp)
app.register_blueprint(jira_bp)

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        app.run(debug=True, port=5000)

models.py

import os
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# Initialize SQLAlchemy (deferred app initialization)
db = SQLAlchemy()

# Ensure the user_databases directory exists
if not os.path.exists('user_databases'):
    os.makedirs('user_databases')

# User model remains in the main database
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True, nullable=False)
    password = db.Column(db.String(100), nullable=False)

# Function to get the SQLAlchemy session for a user's database
def get_user_db_session(username):
    user_db_path = f"user_databases/{username}.db"
    user_engine = create_engine(f"sqlite:///{user_db_path}")
    session_factory = sessionmaker(bind=user_engine)
    return scoped_session(session_factory)

def create_user_db(username):
    user_db_path = f"user_databases/{username}.db"
    if not os.path.exists(user_db_path):
        user_engine = create_engine(f"sqlite:///{user_db_path}")
        Base.metadata.create_all(user_engine)

# Project and Issue models for the user-specific database
Base = declarative_base()

class Client(Base):
    __tablename__ = 'client'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    projects = db.relationship('Project', backref='client', lazy=True)

class Project(Base):
    __tablename__ = 'project'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    client_id = db.Column(db.Integer, db.ForeignKey('client.id'), nullable=False)
    issues = db.relationship('Issue', backref='project', lazy=True)

class Issue(Base):
    __tablename__ = 'issue'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False)
    content = db.Column(db.Text)

auth.py

@auth_bp.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')
    
    session['username'] = username

    # Print debug info
    print("Session stored username for Login:")
    print(session.get("username"))

    # Simulate an external API call
    url = 'https://urchin-app-veelh.ondigitalocean.app/api/login'
    headers = {'Content-Type': 'application/json'}
    data = {"username": username, "password": password}
    new_response = requests.post(url, json=data, headers=headers)

    if new_response.status_code >= 200 and new_response.status_code <= 300:
        json_response = new_response.json()
        refresh_token = json_response.get('refreshToken')
        
        # Handle user database
        user = User.query.filter_by(username=username).first()
        if not user:
            create_user_db(username)
        
        return jsonify(success=True, user=username, token=refresh_token, message='Username and password match.')
    else:
        return jsonify(success=False, message='Incorrect username or password. Please try again.')

project.py

@project_bp.route('/home', methods=['GET'])
def home_internal():
    print("Backend /home API reached")
    print("Session stored username for Home:")
    print(session.get("username"))
    
    username = session.get('username')
    if not username:
        return jsonify(success=False, message='Username not found in session.')

    user_db_session = get_user_db_session(username)
    clients = user_db_session.query(Client).all()
    projects = user_db_session.query(Project).all()

    has_clients = len(clients) > 0
    has_projects = len(projects) > 0

    return jsonify(success=True, has_clients=has_clients, has_projects=has_projects)

I tried using a simpler version without a frontend that did the trick, funnily enough as similar as it looks to my little project; it still returns None for the username variable in session; here's the dummy that works perfectly using session.

app.py

from flask import Flask
from flask_session import Session

app = Flask(__name__)

# Configuration for the session
app.config['SECRET_KEY'] = 'supersecretkey'
app.config['SESSION_TYPE'] = 'filesystem'
Session(app)

# Registering blueprints (each blueprint corresponds to a module)
from create_session import create_session_bp
from print_session import print_session_bp
from print_session_again import print_session_again_bp

app.register_blueprint(create_session_bp)
app.register_blueprint(print_session_bp)
app.register_blueprint(print_session_again_bp)

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

create_session.py

from flask import Blueprint, session

create_session_bp = Blueprint('create_session_bp', __name__)

@create_session_bp.route('/create_session')
def create_session():
    session['username'] = 'test_user'
    return "Session variable 'username' set to 'test_user'. <a href='/print_session'>Go to Print Session</a>"

print_session.py

from flask import Blueprint, session

print_session_bp = Blueprint('print_session_bp', __name__)

@print_session_bp.route('/print_session')
def print_session():
    username = session.get('username', 'Session variable not set!')
    return f"Session variable 'username' is: {username}. <a href='/print_session_again'>Go to Print Session Again</a>"

print_session_again.py

from flask import Blueprint, session

print_session_again_bp = Blueprint('print_session_again_bp', __name__)

@print_session_again_bp.route('/print_session_again')
def print_session_again():
    username = session.get('username', 'Session variable not set!')
    return f"Session variable 'username' is still: {username}."

1 Answer 1

0

I wasn't including the credentials from the frontend which ultimately meant not having the session data received, hence; we had empty values after each request!!

a small before/after example:

const response = await fetch('api/here');
const response = await fetch('api/here', {credentials: 'include'});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.