返回顶部

flask-自定义扩展

简介

使用场景:有很多蓝图,其中只有account蓝图不需要做登录验证,其他视图都要做登录验证,一般有两个办法:

  1.在每一个需要做验证的蓝图中加上before_request装饰器函数(太麻烦)

  


@home.before_request
def bf():
user_dict = session.get('user_info')
if not user_dict:
return redirect('/login')

  2.在全局做配置

from flask import Flask, current_app
from flask_sqlalchemy import SQLAlchemy
from flask_session import Session

# 包含了SQLALchemy的所有操作
db = SQLAlchemy()
auth = Auth()
def check_login():
  user_dict = session.get('user_info')
   if not user_dict:
     return redirect('/login')

def create_app():

app = Flask(__name__)
app.debug = True
app.config.from_object('settings.DevelopmentConfig')

from .views import account
from .views import home
app.register_blueprint(account.ac)
app.register_blueprint(home.home)
Session(app)

db.init_app(app)
app.before_request(check_login)

return app
## 可以这么做,但是不太符合flask开发规范。修改一下,效果sqlalchemy一样,通过一个init_app的函数来做。

引入Auth类


from flask import redirect, session, request


class Auth:

def __init__(self, app=None):

self.app = app
if app:
self.init_app(app)

def init_app(self, app):
app.auth_manager = self # 把当前app赋值给auth_manager

self.app = app
app.before_request(self.check_login)
app.context_processor(self.context_processor) # 我们的定义变量在所有模板中可见

def check_login(self):
if request.path in ['/login', '/register']:
return

user = session.get('user_info')
if not user:
return redirect('/login')

def context_processor(self):
user = session.get('user_info')
return dict(current_user=user)

def login(self, data):
session['user_info'] = data

def logout(self):
"""
将用户登录信息,放入session
:param data:
:return:
"""
del session['user_info']

这样,在返回app前,就通过auth.iinit_app(app)就可以达到全局的效果,并且可以过滤其他URL。

from flask import Flask, current_app
from flask_sqlalchemy import SQLAlchemy
from flask_session import Session

from exts.auth import Auth

# 包含了SQLALchemy的所有操作
db = SQLAlchemy()
auth = Auth()


def create_app():

    app = Flask(__name__)
    app.debug = True
    app.config.from_object('settings.DevelopmentConfig')

    from .views import account
    from .views import home
    app.register_blueprint(account.ac)
    app.register_blueprint(home.home)
    Session(app)

    db.init_app(app)
    auth.init_app(app)
    return app

 

把认证相关的功能放在一个类中,用户登录注销通过current_app直接调用相关功能。

@ac.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        form = LoginForm()
        return render_template('login.html', form=form)

    form = LoginForm(formdata=request.form)
    if not form.validate():
        return render_template('login.html', form=form)

    user = request.form.get('user')
    pwd = request.form.get('pwd')

    user_obj = db.session.query(models.Users).filter(models.Users.name == user, models.Users.pwd == pwd).first()
    db.session.remove()
    if not user_obj:
        return render_template('login.html', msg='用户名或密码错误!', form=form)

    uid = str(uuid4())
    current_app.auth_manager.login({'id': uid, 'user': user_obj.name})
    return redirect('/index')

 

posted @ 2020-10-05 20:24  muguangrui  阅读(236)  评论(0编辑  收藏  举报