Part0
A Big Picture!
Part1
demo.py
Part2
LoginManager.init
|
V
LoginManager.init_app
|
V
设置:login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login'
|
V
class User(UserMixin, db.Model)
|
V
class UserMixin
|
V
@login_manager.user_loader -> login_manager.user_callback = load_user(user_id)
|
V
What happens? -> login_user(user, form.remember_me.data) IMPORTANT<--- 6
| user 继承UserMixin, db.Model
| id_attribute = 'get_id' # 可以自己设置而不使用默认值?
| user_id = user.get_id() = text_type(user.id) # 也就是表中的Primary key!!!
换句话说也就是唯一确定user.
| 在session中设置相应的key-value
| 将user保存在_request_ctx_stack.top中.
| 发送user_logged_in的信号. _get_current_object()/_get_user()
| end
|
V
@login_required
| if request.method in EXEMPT_METHODS, ['OPTIONS'] ???
| if current_app.login_manager._login_disabled;
| if not current_user.is_authenticated:
| 我们只能根据新来的request中的session来
| 判断是不是同样一个user.
| current_user = LocalProxy(lambda: _get_user())
| if has_request_context() and not hasattr(_request_ctx_stack.top, 'user'):
current_app.login_manager._load_user()
| 很明显新到来的request并没有user这个属性,这个属性是在登录的时候会设置.之后的request不会设置.
| 那么会如何_load_user()呢?我想肯定会根据session中的内容.登录的时候不是设置过相应的key-value么?
| _load_user():
| 首先发送一个信号.
| 然后检查session_protection.
| is_missing_user_id ? No
| self.reload_user()
| reload_user() <--- @login_manager.user_loader是在这里发生作用的.
| 所谓reload_user就是从session中获取user_id,然后重新加载user.并放入到request_ctx中.
| 于是current_user.is_authenticated,执行相应的路由函数.