FLask-Login 用户登录简单例子

配置

对于登录系统,我们将会使用到扩展,Flask-Login。配置情况如下(文件 app/init.py):
from flask_login import LoginManager
lm = LoginManager()
lm.init_app(app)

重构用户模型

Flask-Login 扩展需要在我们的 User 类中实现一些特定的方法。但是类如何去实现这些方法却没有什么要求。
class User(db.Model):
    __tablename__ = 'User'
    UserID = db.Column(db.Integer, primary_key=True)
    UserName = db.Column(db.String(15))
    UserEmail = db.Column(db.String(45))
    UserTEL = db.Column(db.String(11))
    UserPassword = db.Column(db.String(200))
    UserType = db.Column(db.Enum("Consumer", "Designer", "Company"), default="Consumer")
    UserImage = db.Column(db.BLOB)
    UserConfirm = db.Column(db.Boolean, default=False)

    def __init__(self, name, email, pwd, type_, confirm):
        self.UserEmail = email
        self.UserName = name
        self.UserPassword = generate_password_hash(pwd)
        self.UserType = type_
        self.UserConfirm = confirm

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        try:
            return unicode(self.UserID)  # python 2
        except NameError:
            return str(self.UserID)  # python 3

    def __repr__(self):
        return '<User %r %d>' % (self.UserName, self.UserID)
  • is_authenticated 方法有一个具有迷惑性的名称。一般而言,这个方法应该只返回 True,除非表示用户的对象因为某些原因不允许被认证。
  • is_active 方法应该返回 True,除非是用户是无效的,比如因为他们的账号是被禁止。
  • is_anonymous 方法应该返回 True,除非是伪造的用户不允许登录系统。
  • 最后,get_id 方法应该返回一个用户唯一的标识符,以 unicode 格式。我们使用数据库生成的唯一的 id。需要注意地是在 Python 2 和 3 之间由于 unicode 处理的方式的不同我们提供了相应的方式。

user_loader 回调

首先,我们必须编写一个函数用于从数据库加载用户。这个函数将会被 Flask-Login 使用:
@lm.user_loader
def load_user(id):
    return User.query.filter(User.UserID == int(id)).first()
请注意在 Flask-Login 中的用户 ids 永远是 unicode 字符串,因此在我们把 id 发送给 Flask-SQLAlchemy 之前,把 id 转成整型是必须的,否则会报错!

登录视图函数

接下来我们需要更新我们的登录视图函数, 下面代码包含了登录与注册功能,原因是登录和注册是同一个html
def login_func(email, password):
    user = User.query.filter_by(UserEmail=email).first()
    if user == None:
        return "NOACCOUNT"
    else:
        if check_password_hash(user.UserPassword, password):
            login_user(user)
            session['userid'] = user.UserID
            session['usertype'] = user.UserType
            return "SUCCEED"
        else:
            return "WRONGPWD"


@auth_.route('/login', methods=['GET', 'POST'])
def login():
    form = RegisterForm(request.form)
    if request.form:
        if request.form['action'] == 'login':
            if g.user is not None and g.user.is_authenticated:
                print g.user.UserName, g.user.UserPassword
                return redirect(url_for('module_a.index_view'))
            if form.validate_on_submit():
                ret = login_func(form.email.data, form.password.data)
                print "login ret : ", ret
                if ret == 'NOACCOUNT' or ret == 'WRONGPWD':
                    flash('Invalid email and/or password.', 'danger')
                    return render_template('login.html', form=form, page='login')
                else:
                    return redirect(url_for('module_a.index_view'))
        elif request.form['action'] == 'register':
            if form.validate_on_submit():
                ret = register_func(form.username.data, form.email.data, form.password.data, form.confirm.data, form.type.data)
                if ret == "INPUTERR":
                    flash('the input too few')
                elif ret == "TYPEERR":
                    flash('No such Type Account')
                elif ret == "PWDERR":
                    flash('Two password are not the same')
                elif ret == "REPEAT":
                    flash('The email have been register')
                if ret == "SUCCEED":
                    return redirect(url_for("auth.unconfirmed"))

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

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

全局变量 g.user

如果你观察仔细的话,你会记得在登录视图函数中我们检查 g.user 为了决定用户是否已经登录。为了实现这个我们用 Flask 的 before_request 装饰器。任何使用了 before_request 装饰器的函数在接收请求之前都会运行。 因此这就是我们设置我们 g.user 的地方
@app.before_request
def before_request():
    g.user = current_user
这就是所有需要做的。全局变量 current_user 是被 Flask-Login 设置的,因此我们只需要把它赋给 g.user ,让访问起来更方便。有了这个,所有请求将会访问到登录用户,即使在模版里

登出

@auth_.route('/logout', methods = ['GET', 'POST'])
@login_required
def logout():
    logout_user()
    return redirect(url_for('module_a.index_view'))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值