如何使用flask-login快速实现用户登录

2,387 阅读3分钟
原文链接: lrenj.top

日期: 2019-08-28

记使用Flask-login实现完整的用户登录流程

安装依赖

$ pip3 install flask-login

用户的初始化

from flask_login import LoginManager, current_user, UserMixin, login_required, login_user, logout_user
login = LoginManager(app)
@login.user_loader
def load_user(user_id):  # 创建用户加载回调函数,接受用户 ID 作为参数
    if user_id == users['id']:
        user = User()
        user.id = user_id
        return user  # 返回用户对象

login.login_view = 'login'
class User(UserMixin):
    pass

id只是用来识别用户的,简单起见直接使用用户名也可以。演示users里只有一个用户,它可以是一个用户列表

login.login_view = 'login'作为默认用户登录视图,所有登录都会路由到/login

User类直接继承UserMixin类简化用户创建的流程

用户信息定义

users =  {'id':'root', 'username': 'root', 'password': '123456'}
#简单起见使用字典直接保存用户信息,正常情况应该使用数据库

登录视图

@app.route('/login',methods=['GET','POST'])
def login():
    next = '' #登陆后的跳转页面凭据
    if request.args.get("next"):
        next = request.args.get("next")

    if request.method == 'POST' and len(next)>0:
        getus = request.form["login[username]"]
        getpw = request.form["login[password]"]
        if getus == users["username"] and getpw == users["password"]:
            curr_user = User()
            curr_user.id = getus
            # 通过Flask-Login的login_user方法登录用户
            login_user(curr_user)

            return redirect(next) #重定向到验证后的页面
        else:
            return redirect(url_for('login')) #如果登录失败就重定向到登录页面

    return render_template('login.html')

需要验证登录的路由

@app.route('/test/')
@login_required
def test():

    return render_template('test.html')

使用@login_required装饰器修饰路由,在进入前需要登录验证

在未验证时返回的是即将跳转的路由,如http://127.0.0.1:5000/?next=/test其中的next键对应的值就是需要跳转的页面地址,所以在/login路由下有一句判断,获取需要跳转的地址,然后使用redirect在登录成功后重定向

if request.args.get("next"):
    next = request.args.get("next")

login页面

创建简单的登录表单

<form class="form-horizontal" method="post">
    <div class="heading">Login</div>
    <div class="form-group">
        <i class="fa fa-user"></i><input required name="login[username]" type="text" autocomplete="off" class="form-control" placeholder="Username" id="exampleInputEmail1">
    </div>
    <div class="form-group">
        <i class="fa fa-lock"></i><input required name="login[password]" type="password" class="form-control" placeholder="Password" />
    </div>
    <div class="form-group">
        <button type="submit" class="btn btn-default"><i class="fa fa-arrow-right"></i></button>
        <span>Don't have an account? <a href="#" class="create_account">Sign up</a></span>
    </div>
</form>

用户名login[username],密码login[password],使用.form[key]的方式获取表单数据

getus = request.form["login[username]"]
getpw = request.form["login[password]"]

用户验证

#从表单获取数据后和本地存储的用户信息对比
if getus == users["username"] and getpw == users["password"]:
    curr_user = User()
    curr_user.id = getus #这里因为id和用户名相同所以省略了id获取uesrname的判断
    # 通过Flask-Login的login_user方法登录用户
    login_user(curr_user)

至此就简单实现了用户登录的流程

用户登出

用户登出需要创建登出的视图/logout

@app.route('/logout')
@login_required
def logout():
    logout_user() #调用登出方法
    return render_template('logout.html')

因为实际的登出并不需要一个页面,所以我们可以在登出完成后重定向回到主页

return redirect(url_for('index'))

页面保护需求

如果只是对某个页面需要登录验证,并且其页面数据只是部分需求验证,即对于访客隐藏部分数据

可以在页面中添加验证

#使用装饰器是最简单的验证方案
@login_required

#还可以使用登录重定向的方式
from flask_login import login_required, current_user

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        if not current_user.is_authenticated:  # 如果当前用户未认证
            return redirect(url_for('index'))  # 重定向到主页
        # ...

使用Jinjia2模板对页面部分数据加密

{% if current_user.is_authenticated %}
<div>
    <p>
        我是加密内容
    </p>
</div>
{% endif %}

在用户未登录时,加密的内容就不会被显示出来

总结

以上便是flask登录的全部流程

  • 初始化applogin = LoginManager(app)
  • 创建用户数据库
  • 创建用户登录视图/login,用户登出视图/logout
  • 初始化用户User类,用户加载函数load_users
  • 在需要登录验证的视图后添加装饰器@login_required
  • 创建登录页面表单
  • 如需页面内容保护,导入current_user
版权声明:文章作者Landers,除非特别声明转载请注明出处,并附上本文链接
本文链接:lrenj.top/blog/post/s…
我的Github地址:Landers1037欢迎关注!