Я знаю, что мы создали объект сеанса с уникальным идентификатором sessionID для ответа клиенту при первом входе пользователя в систему, а затем, когда пользователь запрашивает другие, они будут запрашивать с куки-файлом с этим ID, поэтому сервер может найти объект сеанса тем, что ID, который будет означать, что пользователь зарегистрировался!Как флажок-логин идентифицирует разных пользователей, которые вошли в систему по сеансу подписки?
Но это однопользовательская ситуация. Я обнаружил, что большинство блогов не говорят, если есть много пользователей для управления, если нам нужно создать много сеансов в памяти для каждого пользователя. Я думаю так!
Но когда я ищу исходный код флеш-входа, я не могу найти коллекцию сеансов для поддержки сеанса для каждого пользователя?
def login_user(user, remember=False, force=False, fresh=True):
'''
Logs a user in. You should pass the actual user object to this. If the
user's `is_active` property is ``False``, they will not be logged in
unless `force` is ``True``.
This will return ``True`` if the log in attempt succeeds, and ``False`` if
it fails (i.e. because the user is inactive).
:param user: The user object to log in.
:type user: object
:param remember: Whether to remember the user after their session expires.
Defaults to ``False``.
:type remember: bool
:param force: If the user is inactive, setting this to ``True`` will log
them in regardless. Defaults to ``False``.
:type force: bool
:param fresh: setting this to ``False`` will log in the user with a session
marked as not "fresh". Defaults to ``True``.
:type fresh: bool
'''
if not force and not user.is_active:
return False
user_id = getattr(user, current_app.login_manager.id_attribute)()
session['user_id'] = user_id
session['_fresh'] = fresh
session['_id'] = _create_identifier()
if remember:
session['remember'] = 'set'
_request_ctx_stack.top.user = user
user_logged_in.send(current_app._get_current_object(), user=_get_user())
return True
Существует один сеанс, чтобы сохранить пользователя, но что, если придет другой пользователь?
# -*- coding: utf-8 -*-
"""
flask.globals
~~~~~~~~~~~~~
Defines all the global objects that are proxies to the current
active context.
:copyright: (c) 2011 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
from functools import partial
from werkzeug.local import LocalStack, LocalProxy
def _lookup_req_object(name):
top = _request_ctx_stack.top
if top is None:
raise RuntimeError('working outside of request context')
return getattr(top, name)
def _lookup_app_object(name):
top = _app_ctx_stack.top
if top is None:
raise RuntimeError('working outside of application context')
return getattr(top, name)
def _find_app():
top = _app_ctx_stack.top
if top is None:
raise RuntimeError('working outside of application context')
return top.app
# context locals
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
current_app = LocalProxy(_find_app)
request = LocalProxy(partial(_lookup_req_object, 'request'))
session = LocalProxy(partial(_lookup_req_object, 'session'))
g = LocalProxy(partial(_lookup_app_object, 'g'))
Я нахожу сессия является глобальной переменной, и является localstack(), но я до сих пор не konw, как это работает?
class Local(object):
__slots__ = ('__storage__', '__ident_func__')
def __init__(self):
object.__setattr__(self, '__storage__', {})
object.__setattr__(self, '__ident_func__', get_ident)
def __iter__(self):
return iter(self.__storage__.items())
def __call__(self, proxy):
"""Create a proxy for a name."""
return LocalProxy(self, proxy)
def __release_local__(self):
self.__storage__.pop(self.__ident_func__(), None)
def __getattr__(self, name):
try:
return self.__storage__[self.__ident_func__()][name]
except KeyError:
raise AttributeError(name)
def __setattr__(self, name, value):
ident = self.__ident_func__()
storage = self.__storage__
try:
storage[ident][name] = value
except KeyError:
storage[ident] = {name: value}
def __delattr__(self, name):
try:
del self.__storage__[self.__ident_func__()][name]
except KeyError:
raise AttributeError(name)
Многие люди говорят, что он будет использовать другой идентификатор потока, чтобы определить, storage[ident][name] = value
, но отключить резьб, она хорошо работает для нескольких пользователей? Я просто нахожу, что он использует переменную current_user для идентификации текущего пользователя, но current_user настолько волшебный! Он не поддерживает сборку пользовательской сессии, а только один current_user для решения проблемы! Я не знаю, как это работает?
def login_required(func):
'''
If you decorate a view with this, it will ensure that the current user is
logged in and authenticated before calling the actual view. (If they are
not, it calls the :attr:`LoginManager.unauthorized` callback.) For
example::
@app.route('/post')
@login_required
def post():
pass
If there are only certain times you need to require that your user is
logged in, you can do so with::
if not current_user.is_authenticated:
return current_app.login_manager.unauthorized()
...which is essentially the code that this function adds to your views.
It can be convenient to globally turn off authentication when unit testing.
To enable this, if the application configuration variable `LOGIN_DISABLED`
is set to `True`, this decorator will be ignored.
.. Note ::
Per `W3 guidelines for CORS preflight requests
<http://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0>`_,
HTTP ``OPTIONS`` requests are exempt from login checks.
:param func: The view function to decorate.
:type func: function
'''
@wraps(func)
def decorated_view(*args, **kwargs):
if request.method in EXEMPT_METHODS:
return func(*args, **kwargs)
elif current_app.login_manager._login_disabled:
return func(*args, **kwargs)
elif not current_user.is_authenticated:
return current_app.login_manager.unauthorized()
return func(*args, **kwargs)
return decorated_view
Итак, где происходит сравнение текущего пользователя sessionID с cookie с коллекцией сеансов, поддерживаемой сервером? Кто-нибудь может мне помочь?
От запроса или печенья? Но это происходит от клиента, я думаю, что сервер запоминает пользователя, записывая его в память с коллекциями сеансов пользователя. Поэтому, если пользователь зарегистрировался, будет один сеанс в коллекциях, содержащий пользователя, тогда может быть сохранен статус пользователя в журнале , Вы говорите, загрузите пользователя из запроса, я не понимаю? – kitian
@kitian Я расширил свой ответ – theodor