需求
对于特定视图,可以提供强制要求用户登录的限制
对于所有视图,无论是否强制要求用户登录,都能获取用户身份信息
简单实现
分析
需求:
强制要求 --- 可以通过装饰器, 进行登录限制的先前处理
所有视图要求 --- 可以采用请求勾子
大致流程:
请求---请求勾子---视图(普通和登录) --> 强制登录 装饰器
技术点:
g变量 勾子函数 @app装饰器等
代码
from flask import Flask, abort, g
app = Flask(__name__)
@app.before_request # 勾子, 每次请求前都会执行, 获取身份
def authentication():
# 一系列验证, 获取
pass
# 找出用户身份
if user_id:
g.user_id = user_id # 输出id
else:
g.user_id = None
'登录判定的装饰器, 装饰视图函数, 实现登录限制访问'
def login_required(func): # 传入函数
def wrapper(*args, **kwargs):
if g.user_id is None:
abort(401)
else:
return func(*args, **kwargs) # 判定通过, 返回该函数
return wrapper
@app.route("/"): # 路由装饰器在最外层
@login_required # 装饰视图函数, 进行判定, 实现限制
def index():
return '用户id是{}'.format(g.user_id)
拓展
'app_context'
创建一个'应用上下文'环境, 可以使current_app, g 在flask应用外(如shell)中能被使用。
# 用法:
with app.app_context():
print(current_app.redis)
'request_context'
创建一个'请求上下文'环境, 可以使request, session在flask应用外(如shell)中能被使用。
# 用法
with app.request_context(environ): # environ = wsgi字典数据
print(request.path)
上下文实现原理简单理解
'Threadlocal 线程局部变量'
from flask import request
request -->全局变量
# request.args.get()
实际上 request.args = { } 有很多值,
get也是封装方法, get可以取对应线程的值
通过with来建立变量与线程间的所属关系, 即上下文环境, 实现调用时能取到对应值的功能。