flask学习笔记(-用户)

Posted SUN_DRAGON

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flask学习笔记(-用户)相关的知识,希望对你有一定的参考价值。

Flask认证扩展

  • Flask-Login:管理已登录用户的用户会话。
  • Werkzeug:计算密码散列值并进行核对。
  • itsdangerous:生成并核对加密安全令牌。

登陆会话

安装Flask扩展

pip install flask-login

若想使用Flask-Login扩展,必须实现以下方法:
Flask-Login要求实现的用户方法

方 法说 明
is_authenticated()如果用户已经登录,必须返回 True ,否则返回 False
is_active()如果允许用户登录,必须返回 True ,否则返回 False 。如果要禁用账户,可以返回 False
is_anonymous()对普通用户必须返回 False
get_id()必须返回用户的唯一标识符,使用 Unicode 编码字符串

But**Flask-Login 提供了一个 UserMixin 类,其中包含这些方法的默认实现,且能满足大多数需求。同时上述的方法变成了实例的属性**(no parentheses)。

from flask.ext.login import LoginManager
#创建实例
login_manager = LoginManager()
#LoginManager 对象的 session_protection 属性可以设为 None 、 'basic' 或 'strong'设为 'strong' 时,Flask-Login 会记录客户端 IP地址和浏览器的用户代理信息,如果发现异动就登出用户。
login_manager.session_protection = 'strong'
#设置登录页面的端点
login_manager.login_view = 'auth.login'

#... ...
#注册
login_manager.init_app(app)



from flask.ext.login import UserMixin
#... ...
class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)

#必须指定回调函数
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))#should return None not raise an exception

视图函数

#“Post/ 重定向 /Get 模式”,提交登录密令的 POST 请求最后也做了重定向
#重定向的地址有两种:
#1、用户访问一个为授权的页面,会显示登录表单,Flask-login会把原地址保存在查询字符串的next参数中,通过flask.request.args.get('next')访问。
#2、回到主页面
@app.route('/login', methods=['GET', 'POST'])
def login():
    # Here we use a class of some kind to represent and validate our
    # client-side form data. For example, WTForms is a library that will
    # handle this for us, and we use a custom LoginForm to validate.
    form = LoginForm()
    if form.validate_on_submit():
        # Login and validate the user.
        # user should be an instance of your `User` class
        login_user(user)#flask-login中的函数,在用户会话中把用户标记为已登录。如果想要实现"Remember me"功能,只需要传递remembeer=True即可。此时:一个cokkie即可保存到用户的电脑上,并且,如果userID没有在会话时,Flask-Login将自动从cookie中恢复。并且这个cookie是防修改的,如果用户尝试修改,这个cookie会被服务器丢弃。

        flask.flash('Logged in successfully.')

        next = flask.request.args.get('next')
        # next_is_valid should check if the user has valid
        # permission to access the `next` url
        if not next_is_valid(next):#检查用户是否有权限访问该next页面
            return flask.abort(400)

        return flask.redirect(next or flask.url_for('index'))
    return flask.render_template('login.html', form=form)

一些视图函数需要登陆之后方可访问,可以使用修饰器:login_required

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

模板中使用
可以使用代理:current_user来访问登陆的用户,且这个可以在任何模板中被访问。

% if current_user.is_authenticated %
  Hi  current_user.name !
% endif %

定制登陆过程
默认情况,当用户在没有登陆企图访问login_required修饰的view时,Flask-login将flash消息(需要在模板中get_flashed_messages()获取)并重定向到login视图。如果没有设置,将会报401错误。
定制login的视图函数

login_manager.login_view = 'auth.login'

定制flash消息

login_manager.login_message = "请登录"

定制消息类型

login_manager.login_message_category = "info"

如果想要更深层的定制,需要实现修饰器函数* LoginManager.unauthorized_handler*

@login_manager.unauthorized_handler
def unauthorized():
    # do stuff
    return a_response

登出视图

from flask.ext.login import logout_user, login_required
@auth.route('/logout')
@login_required
def logout():
    logout_user()#删除并重置用户会话,随后显示一条Flash消息
    flash('You have been logged out.')
    return redirect(url_for('main.index'))

密码安全性

Werkzeug 中的 security 模块能够很方便地实现密码散列值的计算。这一功能的实现只需要两个函数,分别用在注册用户和验证用户阶段。

• generate_password_hash(password, method= pbkdf2:sha1 ,salt_length=8) :这个函数将原始密码作为输入,以字符串形式输出密码的散列值,输出的值可保存在用户数据库中。method 和 salt_length 的默认值就能满足大多数需求。
• check_password_hash(hash, password) :这个函数的参数是从数据库中取回的密码散列值和用户输入的密码。返回值为 True 表明密码正确。

from werkzeug.security import generate_password_hash, check_password_hash
class User(db.Model):
# ...
    password_hash = db.Column(db.String(128))
    @property
    def password(self):
        raise AttributeError('password is not a readable attribute')
    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)
    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

加密令牌

对于某些特定类型的程序,有必要确认注册时用户提供的信息是否正确。常见要求是能通过提供的电子邮件地址与用户取得联系。

为验证电子邮件地址,用户注册后,程序会立即发送一封确认邮件。新账户先被标记成待确认状态,用户按照邮件中的说明操作后,才能证明自己可以被联系上。账户确认过程中,往往会要求用户点击一个包含确认令牌的特殊 URL 链接。

使用 itsdangerous 生成确认令牌
一般确认邮件的链接为:http://www.example.com/auth/confirm/<id>其中 id 是数据库分配给用户的数字 id.用户点击链接后,处理这个路由的视图函数就将收到的用户 id 作为参数进行确认,然后将用户状态更新为已确认。但这种实现方式显然不是很安全.解决方法是把 URL 中的 id 换成将相同信息安全加密后得到的令牌。

Flask 使用加密的签名 cookie 保护用户会话,防止被篡改。这种安全的 cookie 使用 itsdangerous 包签名。同样的方法也可用于确认令牌上。

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from flask import current_app
from . import db
class User(UserMixin, db.Model):
# ...
    confirmed = db.Column(db.Boolean, default=False)
    def generate_confirmation_token(self, expiration=3600):
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps('confirm': self.id)
    def confirm(self, token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except:
            return False
        if data.get('confirm') != self.id:
            return False
        self.confirmed = True
        db.session.add(self)
        return True

官方学习

以上是关于flask学习笔记(-用户)的主要内容,如果未能解决你的问题,请参考以下文章

flask学习笔记(-用户)

电子密令卡

python 框架Flask学习笔记之session

flask学习笔记1

千锋Flask学习笔记

千锋Flask学习笔记