Flask(2):登陆验证

装饰器补充:

import functools

def auth(func):
    @functools.wraps(func)  # 作用:把原函数的原信息封装到 inner 中 
    def inner(*args,**kwargs):
        ret = func(*args,**kwargs)
        return ret
    return inner
    
@auth
def index():
    print("index")

# function.__name__  # 获取函数名
print(index.__name__)  # 没加 functools.wraps 这个装饰器的时候, index.__name__ 是 "inner";加了 functools.wraps 之后,index.__name__ 就是 "index"

登陆认证:

登陆认证:某些页面只有登陆之后才能访问

# 方式一:
# 在需要登陆认证的视图函数中加上以下验证代码:
if not session.get("user"):  # 获取 session
    return redirect("/login")
# 该方式的缺点:假如需要认证的视图特别多,则需要在每个视图中添加上述代码

# 方式二:
# 利用自定义装饰器
def auth(func):
    def inner(*args,**kwargs):
        # 先判断是否已经登陆过
        if not session.get("user"):  # 获取 session
            return redirect("/login")
        func(*args,**kwargs)
    return inner
# 然后给需要认证的视图加上上述装饰器

# 方式三:
# 利用 before_request 装饰器
@app.before_request
def auth():
    # 如果是 "/login" 登陆路径,则让其继续走下面的视图函数
    if request.path == "/login":  # request.path :获取路径
        return None
    if session.get("user"):  # 获取 session
        return None
    return redirect("/login")
# @app.before_request  # 装饰器(需要导入)作用:before_request 装饰的函数 在所有视图函数执行之前 都会先被执行;如果遇到了 return xxx,后面的视图函数就不会再走,遇到 return None 则会继续走下面的视图函数(就像是 Django 中间件 process_request 中的 return 一样)

方式二的示例代码:

settings.py

class DevelopmentConfig(object):
    SECRET_KEY = "vnasioeyh"  # session相关(加盐加密)

login_verification.py

from flask import Flask, request, render_template, redirect, session
import functools

app = Flask(__name__)
app.config.from_object("settings.DevelopmentConfig")  # 设置配置文件:settings.py 文件中的 DevelopmentConfig 这个类


def auth(func):
    @functools.wraps(
        func)  # 加上该装饰器的原因:以 index() 为例,经 auth 装饰过的 index函数 是 inner,然后 inner函数和"/index"这个路径绑定, 假如有好多视图函数都加上了这个装饰器,那么 inner 函数就会和好多路径绑定, Flask就不知道你绑定的是哪一个
    def inner(*args, **kwargs):
        # 先判断是否已经登陆过
        if not session.get("user"):  # 获取 session
            return redirect("/login")
        func(*args, **kwargs)

    return inner


@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "GET":
        return render_template("login.html")

    username = request.form.get("username")
    password = request.form.get("psw")
    if username == "neo" and password == "abc123":
        session["user"] = username  # 设置 session
        return redirect("/index")
    else:
        return render_template("login.html", error="用户名密码错误")  # 传递参数也可用字典


@app.route("/index")
@auth  # 登陆认证的装饰器应该写在 app.route() 下面,这样 被 auth() 装饰后的 index() 函数能够作为一个整体(即 inner函数) 再被 app.route() 去装饰,即 被 auth() 装饰的 index() 这个整体,经过 app.route("/index") 装饰后 与 "/index" 这个路径 绑定
def index():
    # 登陆之后才能访问 index 页面
    return render_template("index.txt")  # 模板后缀不影


if __name__ == "__main__":
    app.run()

猜你喜欢

转载自www.cnblogs.com/neozheng/p/9775887.html