pythonauthenticationflaskcookiesflask-login

Flask-Login does not set authentication cookies after successful login


The session cookie (session) is not set in the server response, which results in the user not being recognized as logged in on other routes.

Code: Login route:

@auth_bp.route('/login', methods=['POST'])
def login():
    data = request.json
    if "login" in data and "password" in data:
        res = login_user_service(data['password'], login=data['login'])
        return redirect(url_for('auth.protected'))

    elif "email" in data and "password" in data:
        res = login_user_service(data['password'], email=data['email'])
        return redirect(url_for('auth.protected'))

    else:
        return jsonify({'error': 'No valid credentials'})

login service:

def login_user_service(password, login=None, email=None):
    print(password, login, email)
    if login:
        # Ищем пользователя по логину
        user = User.query.filter_by(login=login).first()
        print(user)

    elif email:
        user = User.query.filter_by(email=email).first()

    else:
        return {"error": "No login or email provided"}

    if user:
        print()
        if bcrypt.check_password_hash(user.password, user.salt+password):
            load_user(user)
            return {"message": "Login successful"}
    return {"error": "Invalid credentials"}

login manager:

@login_manager.user_loader
def load_user(user_id):
    return User.query.filter_by(user_id=user_id).first()

Here’s how I call login_user:

if user and bcrypt.check_password_hash(user.password, user.salt + password):
login_user(user.user_id)
return {"message": "Login successful"}

Ensured SECRET_KEY is set and session settings are configured:

app.secret_key = 'my_secret_key'
app.config\['SESSION_COOKIE_SECURE'\] = False
app.config\['SESSION_COOKIE_HTTPONLY'\] = True
app.config\['SESSION_COOKIE_SAMESITE'\] = 'Lax'

Solution

  • Why do you have load_user(user) in your login_user_service? In that function you should be passing the user instance to the login_user function.

    def login_user_service(password, login=None, email=None):
        ...
        if user:
            if bcrypt.check_password_hash(user.password, user.salt+password):
                # load_user(user)  # wrong function call
                login_user(<user_instance>)  # correct function call
                return {"message": "Login successful"}
        return {"error": "Invalid credentials"}