Flask-Login提供Flask的用户会话管理。它处理登陆、登出任务,并且记住你的会话一段时间。
它能做到的:
- 存储在会话中的活跃用户,让你很轻松的登入登出
- 可以让你限制未登陆的用户访问某些页面
- 处理“记住我”的功能
- 帮你保护你的会话cookie不被小偷偷走
- 很轻松的集成到Flask-Principal或其他授权扩展
它不会做的:
- 强制你使用某个数据库或者存储,你必须完全负责用户的加载
- 限制你使用用户名和密码,OpenID,或任何其它的认证方法
- 处理你登入或登出之外的权限
- 处理用户注册或账户恢复
配置你的程序?
应用程序使用Flask-Loing最重要的类是 LoginManager 。您可以在程序中任何地方创建一个, 像这样:
login_manager = LoginManager()
登录管理器包含允许您的应用程序的代码和Flask-Login一起工作,比如如何加载用户的ID,在发送用户时需要登录,等等。
一旦创建了实际应用对象,您可以配置为登录:
login_manager.init_app(app)
它怎样工作?
您将需要提供一个 user_loader 回调。这个回调用于通过在会话中存储的ID来加载用户对象,它应该使用用户的 unicode ID ,并返回相对应的用户对象。例如:
@login_manager.user_loaderdef load_user(userid):return User.get(userid)
它应该返回 None ( 不要抛出一个异常) 如果ID无效. (在这种情况下,ID应该手动的进行删除然后处理为继续运行。)
一旦用户认证通过,你可以通过函数 login_user 进行登入,例如:
@app.route("/login", methods=["GET", "POST"])def login():form = LoginForm()if form.validate_on_submit():# login and validate the user...login_user(user)flash("Logged in successfully.")return redirect(request.args.get("next") or url_for("index"))return render_template("login.html", form=form)
它是如此简单。 你可以通过 current_user 代理获取用户,这个代理在整个模板中都是有效的:
{% if current_user.is_authenticated() %} Hi {{ current_user.name }}! {% endif %}
页面如果需要用户登录才可以访问可以使用 login_required 装饰器:
@app.route("/settings")@login_requireddef settings():pass
当用户需要登出时:
@app.route("/logout")@login_requireddef logout():logout_user()return redirect(somewhere)
它们即将登出,会话中的cookie将被全部清除。
创建您的用户类?
您使用用户类必须自行实现您的用户类的属性和方法:
- is_authenticated
- Returns True if the user is authenticated, i.e. they have provided valid credentials. (Only authenticated users will fulfill the criteria of login_required.)
- is_active
- Returns True if this is an active user - in addition to being authenticated, they also have activated their account, not been suspended, or any condition your application has for rejecting an account. Inactive accounts may not log in (without being forced of course).
- is_anonymous
- Returns True if this is an anonymous user. (Actual users should return False instead.)
- get_id()
- Returns a unicode that uniquely identifies this user, and can be used to load the user from the user_loader callback. Note that this must be a unicode - if the ID is natively an int or some other type, you will need to convert it to unicode.
从 UserMinix继承,实现用户类更简单,它提供了这些方法的默认实现。(它不是必须的,尽管)
定制登陆流程?
默认情况下,当用户登录某个需要 login_required 认证的页面,而此时用户并没有登陆, Flask-Login 会闪现一个信息并将他们导航到登陆视图(如果登陆视图没有设置,它会报401错误)
登陆视图的名称可以使用 LoginManager.login_view设置。例如:
login_manager.login_view = "users.login"
默认的闪现消息时请登陆后再查看该页面。 如果定制该信息,请使用, LoginManager.login_message:
login_manager.login_message = u"Bonvolu ensaluti por uzi tio pa?o."
定制信息的目录,请使用LoginManager.login_message_category :
login_manager.login_message_category = "info"
视图中有1个next选项指向您想查看的页面,当登入后,它会直接跳转到您要查看的页面。
如果您想进一步定制该流程,请使用函数 LoginManager.unauthorized_handler:
@login_manager.unauthorized_handlerdef unauthorized():# do stuffreturn a_response
用认证头来登陆?
注意
这个方法即将禁用,请使用 request_loader.
有时,你想使用认证头来支持基本认证,比如api请求。为了支持通过认证头来登陆你必须提供 header_loader 回调。这个调用的行为必须符合 user_loader 调用, 除非他使用user id来代替认证头,例如:
@login_manager.header_loaderdef load_user_from_header(header_val):header_val = header_val.replace(‘Basic ‘, ‘‘, 1)try:header_val = base64.b64decode(header_val)except TypeError:passreturn User.query.filter_by(api_key=header_val).first()
默认认证头的值由 header_loader 回调传递。你也可以使用 AUTH_HEADER_NAME 来配置使用。
定制使用请求器来登陆?
有时你想不通过cookie取登陆用户,例如使用认证头或api键值通过查询参数。这种情况下,你可以使用request_loader 回调。这个回调的行为应该和 user_loader回调相同,除非你使用user_id。
例如,使用认证头支持通过url参数和基本认证进行登录:
@login_manager.request_loaderdef load_user_from_request(request):# first, try to login using the api_key url argapi_key = request.args.get(‘api_key‘)if api_key:user = User.query.filter_by(api_key=api_key).first()if user:return user# next, try to login using Basic Authapi_key = request.headers.get(‘Authorization‘)if api_key:api_key = api_key.replace(‘Basic ‘, ‘‘, 1)try:api_key = base64.b64decode(api_key)except TypeError:passuser = User.query.filter_by(api_key=api_key).first()if user:return user# finally, return None if both methods did not login the userreturn None
匿名用户?
默认情况下,当用户没有登录的时候, current_user设置为一个 AnonymousUserMixin对象。它有下面的属性和方法:
如果你对匿名用户有特殊需求,(例如,你需要一个权限字段),你可以提供一个回调,用 LoginManager来创建匿名用户:
login_manager.anonymous_user = MyAnonymousUser
记住我?
“记住我”功能可以巧妙的实现。然而,Flask-Login让它更简单易懂-仅仅传递remember=True给 login_user回调即可。一个cookie即将保存到用户的电脑中,Flask-Login会在会话中没有该cookie时,进行从cookie中恢复, 这个cookie是防干扰的,用户如果干扰了它(比如在里面插入一些信息),这个cookie就会被拒绝,因为会话中没有该cookie。这个是自动发生的。然而,你可以提供额外的防护来保护您的敏感数据。
选择令牌?
使用用户ID的值作为记住令牌不是安全的,更安全的是一个使用用户名和密码的散列值或类似的值。要添加另一个令牌,请使用下面的方法添加到您的用户对象中:
- get_auth_token()
- Returns an authentication token (as unicode) for the user. The auth token should uniquely identify the user, and preferably not be guessable by public information about the user such as their UID and name - nor should it expose such information.
相应的,你应该设定一个 LoginManager的 token_loader函数,它提供一个令牌,并且返回适当的用户对象
make_secure_token 函数用于创建身份验证令牌提供了方便。它将连接所有的参数,然后应用的HMAC密钥,以确保最大的密码安全。(如果你永久在数据库中存储用户的令牌,那么您可能希望将随机数据添加到令牌,进一步阻碍了猜测。)
如果您的应用程序使用密码对用户进行身份验证,包括密码(或咸密码散列你应该使用)的身份验证令牌将确保如果用户更改密码,旧身份验证令牌将不再有效。
新登录?
当用户登录时,他们的会话被标记为“新鲜”,这意味着他们实际上经过身份验证的会话。 当他们的会话被摧毁,他们被记录在“记住我”的饼干,它被标记为“non-fresh “ login_required并不区分新鲜,这对于大多数页面很好。 然而,敏感的改变一个人的个人信息等操作需要重新登录。 (像改变密码这种行为无论如何都需要重新登录)。
fresh_login_required,除了验证用户登录,也将确保他们的登录是否新鲜。 如果没有,它将发送到一个页面,在那里他们可以重新输入他们的凭证。 您可以自定义其行为在同样的方式你可以定制login_required,通过设置 LoginManager.refresh_view, needs_refresh_message,和 needs_refresh_message_category:
login_manager.refresh_view = "accounts.reauthenticate"login_manager.needs_refresh_message = (u"To protect your account, please reauthenticate to access this page.")login_manager.needs_refresh_message_category = "info"
Or by providing your own callback to handle refreshing:
@login_manager.needs_refresh_handlerdef refresh():# do stuffreturn a_response
To mark a session as fresh again, call the confirm_login function.
设置Cookie?
cookie的细节可以在应用程序设置中进行定制。
REMEMBER_COOKIE_NAME | The name of the cookie to store the “remember me” information in. Default: remember_token |
REMEMBER_COOKIE_DURATION | The amount of time before the cookie expires, as a datetime.timedelta object. Default: 365 days (1 non-leap Gregorian year) |
REMEMBER_COOKIE_DOMAIN | If the “Remember Me” cookie should cross domains, set the domain value here (i.e. .example.com would allow the cookie to be used on all subdomains of example.com). Default: None |
REMEMBER_COOKIE_PATH | Limits the “Remember Me” cookie to a certain path. Default: / |
会话保护?
的 虽然上面的功能帮助你安全的“记住我”牌饼干小偷,会话cookie仍然是脆弱的。 Flask-Login包括会话的保护来防止用户的会话被偷了。
您可以配置会话LoginManager保护,和应用程序的配置。 如果启用了它,它可以在基本或强大的模式。 设置在LoginManager,session_protection属性设置为“基本”或“强”:
login_manager.session_protection = "strong"
或者,禁用它:
login_manager.session_protec tion = None
默认情况下,它在“基本”模式被激活。 它可以禁用应用程序的配置通过SESSION_PROTECTION设置设置为None,“基本的”,或“强劲”。
当会话保护启用,每个请求会为 用户的计算机 生成一个标识符(基本上,MD5哈希的IP地址和用户代理)。 如果会话没有一个相关的标识符,将存储生成的一个。 如果它有一个标识符,它匹配生成,然后请求OK。
如果标识符在基本模式不匹配,或者当会话是永久性的,那么会话将被标记为non-fresh,和任何需要一个新的登录将迫使用户认证。 (当然,你必须已经使用新的登录来产生影响。)
如果标识符在强大的模式不匹配非永久性会话,然后整个会话(以及记住牌如果它存在的话)被删除。
本地化?
默认情况下, LoginManager使用flash来显示消息当用户需要登录。 这些信息都是英文的。 如果你需要本地化,LoginManager 的localize_callback属性设置为一个函数,该函数被调用在与这些消息之前发送到flash,例如gettext。 这个函数将将其返回值发送到flash。
API文档?
This documentation is automatically generated from Flask-Login’s source code.
Configuring Login?
- class flask.ext.login.LoginManager( app=None, add_context_processor=True) [source] ?
- This object is used to hold the settings used for logging in. Instances of LoginManager are not bound to specific apps, so you can create one in the main body of your code and then bind it to your app in a factory function.
General Configuration
unauthorized Configuration
needs_refresh Configuration
- needs_refresh_handler( callback) [source] ?
- This will set the callback for the needs_refresh method, which among other things is used by fresh_login_required. It takes no arguments, and should return a response to be sent to the user instead of their normal view.
Parameters: callback (callable) – The callback for unauthorized users. - needs_refresh_message ?
- The message to flash when a user is redirected to the reauthentication page.
- refresh_view ?
- The name of the view to redirect to when the user needs to reauthenticate.
- unauthorized_handler( callback) [source] ?
- This will set the callback for the unauthorized method, which among other things is used by login_required. It takes no arguments, and should return a response to be sent to the user instead of their normal view.
Parameters: callback (callable) – The callback for unauthorized users. - login_message ?
- The message to flash when a user is redirected to the login page.
- login_view ?
- The name of the view to redirect to when the user needs to log in. (This can be an absolute URL as well, if your authentication machinery is external to your application.)
- anonymous_user ?
- A class or factory function that produces an anonymous user, which is used when no one is logged in.
- token_loader( callback) [source] ?
- This sets the callback for loading a user from an authentication token. The function you set should take an authentication token (a unicode, as returned by a user’s get_auth_token method) and return a user object, or None if the user does not exist.
Parameters: callback (callable) – The callback for retrieving a user object. - header_loader( callback) [source] ?
- This sets the callback for loading a user from a header value. The function you set should take an authentication token and return a user object, or None if the user does not exist.
Parameters: callback (callable) – The callback for retrieving a user object. - user_loader( callback) [source] ?
- This sets the callback for reloading a user from the session. The function you set should take a user ID (a unicode) and return a user object, or None if the user does not exist.
Parameters: callback (callable) – The callback for retrieving a user object. - Flash LoginManager.needs_refresh_message to the user.
- Redirect the user to LoginManager.refresh_view. (The page they were attempting to access will be passed in the next query string variable, so you can redirect there if present instead of the homepage.)
- needs_refresh() [source] ?
- This is called when the user is logged in, but they need to be reauthenticated because their session is stale. If you register a callback with needs_refresh_handler, then it will be called. Otherwise, it will take the following actions:
If LoginManager.refresh_view is not defined, then it will simply raise a HTTP 403 (Forbidden) error instead.
This should be returned from a view or before/after_request function, otherwise the redirect will have no effect. - Flash LoginManager.login_message to the user.
- If the app is using blueprints find the login view for the current blueprint using blueprint_login_views. If the app is not using blueprints or the login view for the current blueprint is not specified use the value of login_view. Redirect the user to the login view. (The page they were attempting to access will be passed in the next query string variable, so you can redirect there if present instead of the homepage.)
- unauthorized() [source] ?
- This is called when the user is required to log in. If you register a callback with LoginManager.unauthorized_handler(), then it will be called. Otherwise, it will take the following actions:
If LoginManager.login_view is not defined, then it will simply raise a HTTP 401 (Unauthorized) error instead.
This should be returned from a view or before/after_request function, otherwise the redirect will have no effect.
Login Mechanisms?
- flask.ext.login.current_user ?
- A proxy for the current user.
- flask.ext.login.login_user( user, remember=False, force=False, fresh=True) [source] ?
- 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).
Parameters: marked as not “fresh”. Defaults to True. :type fresh: bool
- user (object) – The user object to log in.
- remember (bool) – Whether to remember the user after their session expires. Defaults to False.
- force (bool) – If the user is inactive, setting this to True will log them in regardless. Defaults to False.
- fresh – setting this to False will log in the user with a session
- flask.ext.login.logout_user() [source] ?
- Logs a user out. (You do not need to pass the actual user.) This will also clean up the remember me cookie if it exists.
- flask.ext.login.confirm_login() [source] ?
- This sets the current session as fresh. Sessions become stale when they are reloaded from a cookie.
Protecting Views?
- flask.ext.login.login_required( func) [source] ?
- 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 LoginManager.unauthorized callback.) For example:
@app.route(‘/post‘)@login_requireddef 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 either of the application configuration variables LOGIN_DISABLED or TESTING is set to True, this decorator will be ignored.Parameters: func (function) – The view function to decorate.
- flask.ext.login.fresh_login_required( func) [source] ?
- If you decorate a view with this, it will ensure that the current user’s login is fresh - i.e. there session was not restored from a ‘remember me’ cookie. Sensitive operations, like changing a password or e-mail, should be protected with this, to impede the efforts of cookie thieves.
If the user is not authenticated, LoginManager.unauthorized() is called as normal. If they are authenticated, but their session is not fresh, it will call LoginManager.needs_refresh() instead. (In that case, you will need to provide a LoginManager.refresh_view.)
Behaves identically to the login_required() decorator with respect to configutation variables.
Parameters: func (function) – The view function to decorate.
User Object Helpers?
- class flask.ext.login.UserMixin [source] ?
- This provides default implementations for the methods that Flask-Login expects user objects to have.
Utilities?
- flask.ext.login.login_url( login_view, next_url=None, next_field=‘next‘) [source] ?
- Creates a URL for redirecting to a login page. If only login_view is provided, this will just return the URL for it. If next_url is provided, however, this will append a next=URL parameter to the query string so that the login view can redirect back to that URL.
Parameters:
- flask.ext.login.make_secure_token( *args, **options) [source] ?
- This will create a secure token that you can use as an authentication token for your users. It uses heavy-duty HMAC encryption to prevent people from guessing the information. (To make it even more effective, if you will never need to regenerate the token, you can pass some random data as one of the arguments.)
Parameters: - *args – The data to include in the token.
- **options (kwargs) – To manually specify a secret key, pass key=THE_KEY. Otherwise, the current_app secret key will be used.
Signals?
See the Flask documentation on signals for information on how to use these signals in your code.
- flask.ext.login.user_logged_in ?
- Sent when a user is logged in. In addition to the app (which is the sender), it is passed user, which is the user being logged in.
- flask.ext.login.user_logged_out ?
- Sent when a user is logged out. In addition to the app (which is the sender), it is passed user, which is the user being logged out.
- flask.ext.login.user_login_confirmed ?
- Sent when a user’s login is confirmed, marking it as fresh. (It is not called for a normal login.) It receives no additional arguments besides the app.
- flask.ext.login.user_unauthorized ?
- Sent when the unauthorized method is called on a LoginManager. It receives no additional arguments besides the app.
- flask.ext.login.user_needs_refresh ?
- Sent when the needs_refresh method is called on a LoginManager. It receives no additional arguments besides the app.
- flask.ext.login.session_protected ?
- Sent whenever session protection takes effect, and a session is either marked non-fresh or deleted. It receives no additional arguments besides the app.