参考
Flask-Login功能
通过 user session,提供登录的常见任务,比如登入 (logging in)、登出 (logging out) 和当前用户 (current user)
login_user()
函数:实现用户的登入,一般在登入的视图函数中调用logout_user()
函数:实现登出功能current_user
属性:获取当前用户,并且方便调取当前用户信息- 对于使用者来说,如果需要页面是授权用户才可见,在相应视图函数前加上
@login_required
装饰器进行声明即可,@login_required
装饰器对于未登录用户访问,默认处理是重定向到LoginManager.login_view
所指定的视图
深入源码理解flask-login:https://blog.csdn.net/jackliu16/article/details/82720104
login_user源码解读:
def login_user(user, remember=False, duration=None, force=False, fresh=True):
# 第一参数为传入的user对象,自己定义!
if not force and not user.is_active:
return False
user_id = getattr(user, current_app.login_manager.id_attribute)()
#login_manager.id_attribute是一个字符串'get_id'。
#因此这句的意思是获取User对象的get_id method,然后执行,从而获取到用户的ID
session['user_id'] = user_id
session['_fresh'] = fresh
session['_id'] = current_app.login_manager._session_identifier_generator()
# 把信息存入session里,Flask的session是以cookie为基础
# 将加密后的cookie发送给客户端,客户端无法篡改cookie
# 但是客户端在往后的请求中携带session中的信息
_request_ctx_stack.top.user = user
# 这里是将user对象存储进当前的request context中
# 之后通过curren_user 就可以根据请求中携带该session信息调取当前用户
user_logged_in.send(current_app._get_current_object(), user=_get_user())
return True
总结:login_user()
函数传入你的user对象,然后实现把你的user对象里面的信息写入session,把session的信息加密生成cookie发给客户端,然后客户端的请求中就可以含有对应session的信息。同时,该函数实现了把当前用户存储user对象进请求上下文,根据请求中的session就可以找到对应的user模型。
@login_required
装饰器源码解读:
# flask_login/utils.py
def login_required(func):
@wraps(func)
def decorated_view(*args, **kwargs):
# 如果request method为例外method,即在EXEMPT_METHODS中的method,可以不必鉴权
# 默认情况下只有OPTIONS method在EXEMPT_METHODS set中
# 而GET、PUT、POST等常见的methods都需要鉴权
if request.method in EXEMPT_METHODS:
return func(*args, **kwargs)
# 如果_login_disabled为True则不必鉴权
elif current_app.login_manager._login_disabled:
return func(*args, **kwargs)
# 正常鉴权
# current_user.is_authenticated为True则正常处理请求,返回视图函数
elif not current_user.is_authenticated:
return current_app.login_manager.unauthorized()
return func(*args, **kwargs)
current_user源码解读:
# flask_login/utils.py
# LocalProxy 是代理,每次调用current_uer,都会重新执行一遍_get_user()方法
# 动态更新
current_user = LocalProxy(lambda: _get_user())
# flask_login/utils.py
def _get_user():
if has_request_context() and not hasattr(_request_ctx_stack.top, 'user'):
# login_user 里面有把user写进request context,但是如果用户没有事先登录就取不到
# 需要执行以下这条命令
current_app.login_manager._load_user()
# 涉及太多cookie等知识,先不管
return getattr(_request_ctx_stack.top, 'user', None)
flask-login使用思路
- 首先是定义user类。Flask-Login 规定 User 类必须实现三个属性和一个方法,最简单的方法是继承
UserMixin
类
@property
def is_active(self):
return True
@property
def is_authenticated(self):
return True
@property
def is_anonymous(self):
return False
def get_id(self):
try:
return text_type(self.id)
except AttributeError:
raise NotImplementedError('No `id` attribute - override `get_id`')