Flask框架之用户登录模块flask_login模块

flask_login模块

flask-login为flask提供了用户会话管理。他处理了日常的登入,登出并且长时间记住用户的会话。

  1. 在会话中存储当前活跃的用户ID让你能够自由地登入和登出。

  2. 让你限制登入或登出,用户可以访问的试图。

  3. 处理让人棘手的记住我功能。

  4. 帮助你保护用户会话免遭cookie被盗的牵连。

  5. .可以与以后可能使用的flask-principal或其他认证扩展集成。


一、配置你的应用

对一个使用flask-login的应用最重要的一部分是loginmanager类。

login_manager = LoginManager()
login_manager.init_app(app)

二、他是如何工作的

必须提供一个user_loader回调。

@login_manager.user_loader
def load_user(userid):
    return User.get(userid)

接受一个用户的unicodeID作为参数,并且返回响应的用户对象。

如果ID无效的话,他应该返回None。

我的理解是:参数user_loader标记的函数虽然在程序中没有显示调用,但是每次程序每次访问login_required标注的函数,都会从session中通过user_id重新加载当前用户对象。


三、你的用户类

你用来标识用户的类需要实现这些属性和方法:

四个方法:

is_authenticated()is_active()is_anonymous()get_id()

  • is_authenticated() 当用户通过验证时,也即提供有效证明是返回true。

  • is_active() 可以直接返回true。

  • is_anonymous() 如果是匿名用户,返回true。真实用户返回False。

  • get_id() 返回一个能唯一识别用户的,并能用于user_loader回调中加载用户的Unicode ID。

要简便的实现用户类,可以从UserMixin继承,他提供了对所有这些方法的默认实现。


四、login示例

一旦用户通过验证,然后把这个对象传给login_user,如果登录信息正确则跳转到指定URL导航界面。在此必须编写回调函数load_user(),用于返回通过id获取数据库的用户对象,在每次访问带有login_required装饰器的试图函数时都会执行回调函数load_user()

@app.route('/login',methods=['GET','POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        login_user(user)
        flask.flash('Logged in successfully.')
@login_manager.user_loader
def load_user(id):
    return user_dal.User_Dal.load_user_byid(id)

这里必须验证next参数,如果不验证,你的应用会收到重定向攻击。

		next = flask.request.args.get('next')
        if not next_is_valid(next):
            return flask.abort(400)
        return flask.redirct(next or flask.url_for('index'))
    return flask.render_template('login.html', form=form)

需要用户登入的视图可以用login_required装饰器来装饰。

@app.route('/settings')
@login_required
def settings():
    pass

当用户需要登出时,使用logout_user方法。

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(somewhere)

他们会被登出,且他们会话产生的任何cookie都会被清理干净。此时再访问@login_required标注的函数,则会弹出401错误。见下👇


五、定制登入过程

默认情况下,当未登录的用户尝试访问一个login_required装饰的视图,flask-login会闪现一条消息并且重定向到登录视图。

如果未设置登录视图,他将会以401错误退出。

登录视图的名称可以通过LoginManager.login_view语句设置成:

login_manager.login_view = 'login_name'
这个login_name是你设置的登录的路由

默认的闪现消息是Please log in to access this page
注意:如果要获得此条闪现信息,可以在上两行提到的login_name路由所在的函数通过get_flashed_messages()获得。

当然你也可以自定义该信息,请设置login_message

login_manager.login_message = u'please log in'

要自定义消息分类,请设置login_message_category

login_manager.login_message_category = 'info'

当重定向到登入视图,他的请求字符串中会有一个next变量,其值为用户之前访问的页面。


六、使用request loader定制登录

有时你想要不使用cookies情况下登录用户,比如使用http头或者一个作为查询参数的api密钥。

这种情况下应该是用request_loader回调。


七、匿名用户

默认情况下,当一个用户没有真正的登录,current_user被设置成一个AnonymousUserMixin对象。

is_active is_authenticated的值为False

is_anonymous的值为true

get_id返回None


八、记住我(remember功能)

在这里插入图片描述
记住我的功能很难实现。但是flask-login几乎透明的实现它。

只要把remember=True传递给login_user

一个cookie将会存储在用户计算机中,如果用户会话中没有用户ID的话,flask-login会自动地从cookie中恢复用户ID。

这里cookie是防篡改的。

该层功能是被自动实现的。


九、会话保护

当上述特性保护记住我令牌免遭cookie窃取时,会话cookie依然是脆弱的。

session_protection的值为basic或者strong。禁用时应设置为None。

默认时被激活为basic模式。

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
用户登录模块是Web应用程序中非常基础的模块之一。在Flask框架中,实现用户登录功能通常需要借助Flask-WTF扩展和Flask-Login扩展。 Flask-WTF扩展提供了表单验证和CSRF保护等功能,而Flask-Login扩展则提供了用户认证和管理功能。 下面是用户登录模块的详细设计: 1. 创建Flask应用程序对象 ```python from flask import Flask app = Flask(__name__) ``` 2. 配置Flask应用程序对象 ```python app.config['SECRET_KEY'] = 'secret_key' app.config['WTF_CSRF_SECRET_KEY'] = 'csrf_secret_key' ``` SECRET_KEY和WTF_CSRF_SECRET_KEY是用于加密和CSRF保护的密钥。可以自行生成,也可以使用随机字符串生成函数。 3. 创建用户登录表单 ```python from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField from wtforms.validators import DataRequired, Length class LoginForm(FlaskForm): username = StringField('Username', validators=[DataRequired(), Length(min=6, max=20)]) password = PasswordField('Password', validators=[DataRequired(), Length(min=6, max=20)]) submit = SubmitField('Login') ``` 用户登录表单包含用户名和密码两个字段以及一个提交按钮。使用wtforms库,可以方便地创建表单和验证表单数据。 4. 创建用户模型 ```python from flask_login import UserMixin class User(UserMixin): def __init__(self, id, username, password): self.id = id self.username = username self.password = password def get_id(self): return str(self.id) ``` 用户模型需要继承Flask-Login扩展的UserMixin类,并实现get_id方法。get_id方法返回一个字符串类型的用户ID,用于Flask-Login扩展的用户认证和管理。 5. 实现用户认证回调函数 ```python from werkzeug.security import check_password_hash users = [ User(1, 'user1', 'password1'), User(2, 'user2', 'password2') ] def authenticate(username, password): for user in users: if user.username == username and check_password_hash(user.password, password): return user def load_user(user_id): for user in users: if user.id == int(user_id): return user ``` authenticate函数用于验证用户身份,如果验证成功返回用户对象,否则返回None。load_user函数用于根据用户ID返回用户对象。 6. 配置Flask-Login扩展 ```python from flask_login import LoginManager login_manager = LoginManager(app) login_manager.login_view = 'login' login_manager.login_message = 'Please login to access this page.' @login_manager.user_loader def load_user(user_id): return load_user(user_id) ``` 配置Flask-Login扩展需要传入Flask应用程序对象。login_view属性设置登录页面的路由名称,login_message属性设置登录提示信息。@login_manager.user_loader装饰器用于指定load_user函数。 7. 实现用户登录路由 ```python from flask import render_template, redirect, url_for, flash, request from flask_login import login_user, logout_user, current_user @app.route('/login', methods=['GET', 'POST']) def login(): form = LoginForm() if form.validate_on_submit(): user = authenticate(form.username.data, form.password.data) if user is not None: login_user(user) next = request.args.get('next') return redirect(next or url_for('index')) else: flash('Invalid username or password.') return render_template('login.html', form=form) ``` 用户登录路由处理函数使用@login_required装饰器保护,只有登录用户才能访问。使用authenticate函数验证用户身份,如果验证成功则调用login_user函数实现用户登录。如果登录成功,则跳转到原始请求页面或首页,否则显示错误信息。 8. 实现用户注销路由 ```python @app.route('/logout') @login_required def logout(): logout_user() return redirect(url_for('index')) ``` 用户注销路由处理函数使用@login_required装饰器保护,只有登录用户才能访问。使用logout_user函数实现用户注销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值