在使用flask-session,flask-sqlalchemy等组件时,我们发现都是导入以后实例化一个类,并将app传入进行使用,或者先实例化一个对象,再利用对象的init_app方法将app传入使用

我们也可以模仿这些组件的做法自定义一个认证组件

首先创建组件的目录和文件

auth.py

from flask import request,session,redirect

class Auth(object):

    def __init__(self,app=None):
        self.app = app
        if app:
            self.init_app(app)

    def init_app(self,app):
        app.auth_manager = self

        self.app = app
        app.before_request(self.check_login)
        app.context_processor(self.context_processor)

    def check_login(self):
        """
        检查用户是否已经登录
        :return:
        """
        if request.path == '/login':
            return

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

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

    def login(self,data):
        """
        将用户登录信息,放入session
        :param data:
        :return:
        """
        session['user'] = data

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

这里要注意app.context_processor方法可以定义一些全局的变量,在所有的视图中都可以渲染使用

同时为了在视图中能使用这个类中的函数,我们在init_app方法中定义了app.auth_manager = self,这样在视图中我们就可以通过导入current_app.auth_manager来得到这个类的对象,从而调用类中的方法了

视图中应用

from flask import blueprints,render_template,request,session,redirect,current_app
from s8day130_pro import models
from s8day130_pro import db
ac = blueprints.Blueprint('ac',__name__)

@ac.route('/login',methods=['GET','POST'])
def login():

    if request.method == 'GET':
        return render_template('login.html')
    else:
        user = request.form.get('user')
        pwd = request.form.get('pwd')

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

        current_app.auth_manager.login(user)
        return redirect('/index')


@ac.route('/logout')
def logout():
    current_app.auth_manager.logout()
    return redirect('/login')

__init__.py中使用自定义组件

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from exts.auth import Auth

# 包含了SQLAlchemy相关的所有操作
db = SQLAlchemy()

from .views.account import ac
from .views.home import hm

def create_app():
    app = Flask(__name__)
    app.config.from_object('settings.DevelopmentConfig')

    app.register_blueprint(ac)
    app.register_blueprint(hm)

    db.init_app(app)
    Auth(app)

    return app

 

posted on 2018-05-04 19:36  Py行僧  阅读(409)  评论(0编辑  收藏  举报