Пользователь, прошедший проверку подлинности Flask-Login и Flask-Principle, переходит к flask_login.AnonymousUserMixin

у меня две проблемы

  1. Мой аутентифицированный пользователь постоянно переходит на flask_login.AnonymousUserMixin
  2. Я получаю неожиданную сигнализацию, используя Flask-Login и Flask-Principal

Попытка получить URL-адрес /projects/10, защищенный с помощью @admin_permission.require(http_exception=403)

Это мой консольный вывод:

127.0.0.1 - - [30/Jul/2013 16:22:58] "GET /projects/10 HTTP/1.1" 302 -
127.0.0.1 - - [30/Jul/2013 16:22:58] "GET /login HTTP/1.1" 200 -

Вход в форму входа (пока все хорошо). Ввод действительного логина и пароля и получение сумасшедших сигналов и поведения - это не то, что я ожидаю:

127.0.0.1 - - [30/Jul/2013 16:24:06] "POST /login HTTP/1.1" 302 -
<Employee('103','Dmitry Semenov')>
<Identity id="103" auth_type="None" provides=set([Need(method='role', value='manager'), Need(method='id', value=103L), Need(method='role', value='admin')])>
<flask_login.AnonymousUserMixin object at 0x03258790>
<Identity id="103" auth_type="None" provides=set([])>
127.0.0.1 - - [30/Jul/2013 16:24:06] "GET /projects/10 HTTP/1.1" 302 -
<flask_login.AnonymousUserMixin object at 0x03342AF0>
<Identity id="103" auth_type="None" provides=set([])>
127.0.0.1 - - [30/Jul/2013 16:24:06] "GET /login HTTP/1.1" 200 -
<flask_login.AnonymousUserMixin object at 0x03342E90>
<Identity id="103" auth_type="None" provides=set([])>

Как вы видите, у меня есть current_user, указывающий на действительный экземпляр Employee (класс) и идентификатор ID = 103, но затем сразу же по какой-то причине он становится flask_login.AnonymousUserMixin, а затем система аутентификации пропускает этого пользователя и не позволяет мне открывать /projects/ 10 URL.

Есть идеи, что не так? И почему я получаю так много сигналов - согласно коду они должны происходить только при успешном входе в систему. Что я упустил?

Исходный код:

# flask-principal
principals = Principal()
normal_role = RoleNeed('normal')
normal_permission = Permission(normal_role)
admin_permission  = Permission(RoleNeed('admin'))
principals._init_app(app)

login_manager    = LoginManager()
login_manager.init_app(app)

@login_manager.user_loader
def load_user(userid):
    return mysqlsess.query(Employee).get(userid)


@app.route("/")
@app.route("/dashboard")
def vDashboard():
    return render_template('dashboard.html')

@app.route('/projects')
def vPojects():
    return "Projects"


@app.route('/projects/<ID>')
@admin_permission.require(http_exception=403)
def vProject(ID):
    return current_user.roles[1]

# somewhere to login    
@app.route('/login', methods=['GET', 'POST'])
def login():
    # A hypothetical login form that uses Flask-WTF
    form = LoginForm()

    # Validate form input
    if form.validate_on_submit():
        # Retrieve the user from the hypothetical datastore
        user = mysqlsess.query(Employee).get(form.email.data)

        # Compare passwords (use password hashing production)
        if form.password.data == str(user.ID):
            # Keep the user info in the session using Flask-Login
            login_user(user)
            # Tell Flask-Principal the identity changed
            identity_changed.send(app,
                                  identity=Identity(user.ID))
            return redirect(session['redirected_from'] or '/')
        else:
            return abort(401)

    return render_template('login.html', form=form)


# somewhere to logout
@app.route("/logout")
def logout():
    logout_user()

    for key in ['identity.name', 'identity.auth_type', 'redirected_from']:
        try:
            del session[key]
        except:
            pass
    return Response('<p>Logged out</p>')


# handle login failed
@app.errorhandler(401)
def page_not_found(e):
    return Response('<p>Login failed</p>')


@app.errorhandler(403)
def page_not_found(e):
    session['redirected_from'] = request.url
    return redirect(url_for('login'))


@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
        identity.user = current_user
        print identity.user


        if hasattr(current_user, 'ID'):
            identity.provides.add(UserNeed(current_user.ID))

        if hasattr(current_user, 'roles'):
            for role in current_user.roles:
                identity.provides.add(RoleNeed(role))

        print identity


class LoginForm(Form):
    email = TextField()
    password = PasswordField()

if __name__ == "__main__":
    app.run()

И мой класс Employee SQLAlchemy

class Employee(Base):

__tablename__  = "Employees"

# Properties
ID           = Column(BigInteger,   primary_key=True)
name         = Column(VARCHAR(255), nullable=False)
created      = Column(DateTime,     nullable=False, default=datetime.now())
updated      = Column(DateTime)
deleted      = Column(DateTime)
branchID     = Column(BigInteger,   ForeignKey('Branches.ID'),    nullable=False)
departmentID = Column(BigInteger,   ForeignKey('Departments.ID'), nullable=False)
utilization  = Column(SmallInteger, nullable=False, default=1)
statusID     = Column(Enum('active', 'fired', 'vacation'), default='active')
birthday     = Column(Date)

# Relationships
Branch       = relationship("Branch")
Department   = relationship("Department")
ProjectStat  = relationship("ProjectStat",  lazy="dynamic")

roles        = ["admin", "manager"]

# Methods
def zzz(self):
    session = object_session(self)

    stats = self.ProjectStat.filter(and_(ProjectStat.metricID=='hb', ProjectStat.metricValue>=6)).all()
    for s in stats:
        print s.metricValue

# Constructor
def __init__(self, ID, name):
    self.ID   = ID
    self.name = name

# Friendly Print
def __repr__(self):
    return "<Employee('%s','%s')>" % (self.ID, self.name)

def is_active(self):
    return True

def get_id(self):
    return unicode(self.ID)

def is_authenticated(self):
    return True

def is_anonymous(self):
    return False

person DmitrySemenov    schedule 30.07.2013    source источник


Ответы (1)


Вам нужно создать экземпляр принципа после входа в систему.

Это повторяющийся вопрос, см. здесь ?lq=1">Вход в Flask и Принципал — current_user является анонимным, несмотря на то, что я вошел в систему

person applewood    schedule 02.12.2014