flask-login:无法理解其工作原理


73

我正在尝试了解其Flask-Login工作原理。

我在他们的文档中看到他们使用了预先填充的用户列表。我想玩一个数据库存储的用户列表。

但是,我不了解本Flask-Login模块中的某些内容。

@login_manager.user_loader
def load_user(userid):
    #print 'this is executed',userid
    return user(userid, 'asdf')

每次请求都会调用此代码吗?这是用来加载我的用户对象的所有详细信息吗?

现在,我有以下代码:

@app.route('/make-login')
def make_login():
    username = 'asdf'
    password = 'asdf'
    user_data = authenticate(username, password)
    user_obj = user(user_data[0], user_data[1])
    login_user(user_obj)
    return render_template('make-login.html')

当我访问/ make-login时,我想登录。

我的用户类别:

class user(object):
    def __init__(self, id, username, active=True):
        self.username = username
        self.id = id
        #self.active = active
    def is_authenticated(self):
        return True  

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return 5

另外,我写了另外两个验证/注册功能

def authenticate(username, password):

    cursor = db.cursor()
    password = md5.md5(password).hexdigest()
    try:
        query = "SELECT * FROM `users` WHERE `username` = %s AND `password` = %s"
        cursor.execute(query, (username, password))
        results = cursor.fetchall()
        #print results[0][0]
        #print "here i am"
        if not results:
            return False
        else:
            user_data = [results[0][0], results[0][1]]
            return user_data
            #self.authenticated = True
            #self.user_id = results[0][0]
            #session['username']  = results['username']
            #print type(results)
    except db.Error, e:
        return 'There was a mysql error'    

def register(username, password, email, *args):
    cursor = db.cursor()
    password = md5.md5(password).hexdigest()
    try:
        #query = "INSERT INTO `users` (`username`, `password`, `email`) VALUES ('%s', '%s', '%s')" % (username, password, email)
        query = "INSERT INTO `users` (`username`, `password`, `email`) VALUES (%s, %s, %s)"
        cursor.execute(query, (username, password, email))
        db.commit()
        return True
    except db.Error, e:
        print 'An error has been passed. %s' %e
        db.rollback()
        return False

我不知道如何使它Flask-Login与MySQL一起使用。另外,我不知道用户是否已登录。如何获得用户ID或用户名?

任何人都可以在某些行中向我解释这Flask-Login是如何工作的?


您的用户类别应大写:User。有关更多信息,请参见Python的样式指南(PEP 8)
所罗门·乌科

Answers:


76

Flask-login实际上没有用户后端,它只是处理会话机制来帮助您登录和注销用户。您必须(通过装饰方法)告诉它,代表用户的是什么,并且还需要您弄清楚如何知道用户是否“活跃”(因为“活跃”可能意味着不同的应用程序会有不同的含义) )。

您应该阅读文档,并确保它可以什么和不可以做什么。在这里,我仅专注于与db后端进行连接。

首先,定义一个用户对象。代表用户的属性。然后,该对象可以查询数据库,LDAP或任何对象,它是将登录机制与数据库后端连接的钩子。

为此,我将使用登录示例脚本。

class User(UserMixin):
    def __init__(self, name, id, active=True):
        self.name = name
        self.id = id
        self.active = active

    def is_active(self):
        # Here you should write whatever the code is
        # that checks the database if your user is active
        return self.active

    def is_anonymous(self):
        return False

    def is_authenticated(self):
        return True

创建用户对象后,需要编写一种加载用户的方法(基本上是User从上面创建该类的实例)。使用用户ID调用此方法。

@login_manager.user_loader
def load_user(id):
     # 1. Fetch against the database a user by `id` 
     # 2. Create a new object of `User` class and return it.
     u = DBUsers.query.get(id)
    return User(u.name,u.id,u.active)

完成这些步骤后,您的登录方法将执行以下操作:

  1. 检查用户名和密码是否匹配(针对您的数据库)-您需要自己编写此代码。

  2. 如果身份验证成功,则应将用户实例传递给 login_user()


23
+1这非常有用---我不太了解Flask-Login的官方文档。
2012年

如果您不想一定要建立数据库后端来对此进行测试,则链接到的要旨特别有用。gist.github.com/bkdinoop/6698956
dino

1
@Burhan Khalid,在示例函数中,def login():... login_user(user)。用户来自哪里?
chfw 2014年

1
@Burhan Khalid,所以我应该把load_user(id)函数放在哪里

我对此也感到困惑。我们如何将ID传递给user_loader装饰器,或者flask如何知道我们使用哪个ID登录?
frlzjosh

16

Flask登录将在每次请求之前尝试加载用户。所以是的,下面的示例代码将在每次请求之前调用。它用于检查当前会话中的用户ID,并将为该ID加载用户对象。

@login_manager.user_loader
def load_user(userid):
    #print 'this is executed',userid
    return user(userid, 'asdf')        

如果您在github上查看Flask-login源代码,则函数init_app下的一行如下:

app.before_request(self._load_user)

因此,在每个请求之前,都会调用_load_user函数。_load_user函数实际上根据条件调用另一个函数“ reload_user()”。最后,reload_user()函数调用您编写的回调函数(在示例中为load_user())。

同样,flask-login仅提供用于登录/注销用户的机制。它不在乎您是否正在使用mysql数据库。


7

根据Flask-Login文档,必须返回一个用户对象,如果未找到用户ID,则应返回None而不是Exception。

@login_manager.user_loader
def load_user(userid):
    try:
        #: Flask Peewee used here to return the user object
        return User.get(User.id==userid)
    except User.DoesNotExist:
        return None

6

您可能要使用Flask-Security,它将Flask-Login与SQLAlchemy结合使用以进行数据库访问,并自动执行许多用户记录的后端处理。

快速入门教程将让你开始。将app.config ['SQLALCHEMY_DATABASE_URI']设置为您的MySQL数据库连接字符串。


0

这是一个使用登录的Flask示例:https : //bitbucket.org/leafstorm/flask-login/src/3160dbfc7cfc/example/login-example.py您需要为每个需要登录的方法使用@login_required。例如,

@app.route('/make-login')
@login_required
def make_login():
    ...

我知道login_required是什么,我需要知道user_loader是什么。但是,我知道这个示例,但是他们不管理数据库中的用户...
Sorin Vladu 2012年

6
至少对于我来说,链接被拒绝了。
volvox
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.