简体   繁体   中英

Why isn't the Flask-Login current_user.is_authenticated consistent?

I have an Angular app that is making API calls to the backend Flask app. The Flask app is using Flask-Login to authenticate users when they login. When the user logs in with the login() function I defined, current_user.is_authenticated returns True . When I call another function called get_is_logged_in() , current_user.is_authenticated returns False .

My User class inherits from UserMixin , so it has all of the required properties and methods as explained in the documentation ( https://flask-login.readthedocs.io/en/latest/#your-user-class ). In the login() function, after calling login_user() , I checked current_user.id to verify that the proper user is being logged in. I also checked current_user.is_anonymous and it returned False , as expected.

user.py

from sqlalchemy import Column, String, Text, Integer
from flask_login import UserMixin
from .database import Base, Session

class User(Base, UserMixin): # Inherits UserMixin
    __tablename__ = "USER"

    id = Column(Integer, primary_key=True)
    email = Column(String(450), unique=True, nullable=False)
    first_name = Column(String, nullable=False)
    last_name = Column(String, nullable=False)
    password = Column(Text, nullable=False)

    def __init__(self, email, first_name, last_name, password):
        self.email = email
        self.first_name = first_name
        self.last_name = last_name
        self.password = password

database.py

from sqlalchemy import create_engine, Column, String, Integer, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import pymssql

db_url = "DB_URL"
db_name = "DB_NAME"
db_user = "DB_USER"
db_password = "DB_PW"
engine = create_engine(f'mssql+pymssql://{db_user}:{db_password}@{db_url}/{db_name}')
Session = sessionmaker(bind=engine)
Base = declarative_base()

main.py

from flask import Flask, jsonify, request
from flask_login import LoginManager, login_user, login_required, 
logout_user, current_user
from .entities.database import Session, engine, Base
from .entities.user import User

import json    
# Other necessary imports

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

@app.route('/api/login', methods=['POST'])
def login():
    try:
        posted_email = request.json['email'].lower()
        posted_password = request.json['password']
        user_json = get_user_by_email(posted_email)

        if not bcrypt.check_password_hash(user_json.get_json() ['password'], posted_password): # The password was incorrect
            return jsonify(success=False, message='The password is incorrect')
        else: # The login was successful, so pass in all user credentials (except password)
            # Get user object from the database
            user = load_user(1) # Hard-coded id for testing

            # Login the user
            login_user(user, remember=False, force=True)

            return jsonify(
                success=True,
                user=current_user.is_authenticated # Returns True
                )
    except KeyError: # A KeyError is only thrown if the user does not exist
        return jsonify(success=False, message='A user with that email does not exist')

@app.route('/api/isLoggedIn', methods=['POST'])
def get_is_logged_in():
    return jsonify(success=current_user.is_authenticated) # Returns False when called

Notice that I am using the declarative base from SQLAlchemy. Any help is appreciated.

return jsonify(
        success=True,
        user=current_user.is_authenticated # Returns True
        )

This will always return true because you're explicitly setting success = True regardless of the value of current_user.is_authenticated

I don't see you calling get_is_logged_in anywhere, but the most obvious reason for it returning false is because current_user.is_authenticated isn't actually equal to True when the function is being called, thus you're setting success to false.

A code snippet of you calling get_is_logged_in would be helpful to know for sure.

There is a chance that the current_user is not being persisted between requests, especially if your methods of calling /api/login and /api/isLoggedIn vary.

The load_user() function will run for each request so you might find it helpful to check the user_i d it is loading each request (ie add a print statement).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM