Flask-Login

Flask-Login provides user session management for Flask. It handles the common tasks of logging in, logging out, and remembering your users’ sessions over extended periods of time.
It will:
  • Store the active user’s ID in the session, and let you log them in and out easily.
  • Let you restrict views to logged-in (or logged-out) users.
  • Handle the normally-tricky “remember me” functionality.
  • Help protect your users’ sessions from being stolen by cookie thieves.
  • Possibly integrate with Flask-Principal or other authorization extensions later on.
However, it does not:
  • Impose a particular database or other storage method on you. You are entirely in charge of how the user is loaded.
  • Restrict you to using usernames and passwords, OpenIDs, or any other method of authenticating.
  • Handle permissions beyond “logged in or not.”
  • Handle user registration or account recovery.

Configuring your Application

The most important part of an application that uses Flask-Login is the LoginManagerclass. You should create one for your application somewhere in your code, like this:
login_manager = LoginManager()
The login manager contains the code that lets your application and Flask-Login work together, such as how to load a user from an ID, where to send users when they need to log in, and the like.
Once the actual application object has been created, you can configure it for login with:
login_manager.init_app(app)

How it Works

You will need to provide a user_loader callback. This callback is used to reload the user object from the user ID stored in the session. It should take the unicode ID of a user, and return the corresponding user object. For example:
@login_manager.user_loader
def load_user(userid):
    return User.get(userid)
It should return None (not raise an exception) if the ID is not valid. (In that case, the ID will manually be removed from the session and processing will continue.)
Once a user has authenticated, you log them in with the login_user function. For example:
@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)
It’s that simple. You can then access the logged-in user with the current_user proxy. Views that require your users to be logged in can be decorated with thelogin_required decorator:
@app.route("/settings")
@login_required
def settings():
    pass
When the user is ready to log out:
@app.route("/logout")
@login_required
def logout():
    logout_user()
    return redirect(somewhere)
They will be logged out, and any cookies for their session will be cleaned up.

Your User Class

The class that you use to represent users needs to implement these methods:
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 Falseinstead.)
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.
To make implementing a user class easier, you can inherit from UserMixin, which provides default implementations for all of these methods. (It’s not required, though.)

Customizing the Login Process

By default, when a user attempts to access a login_required view without being logged in, Flask-Login will flash a message and redirect them to the log in view. (If the login view is not set, it will abort with a 401 error.)
The name of the log in view can be set as LoginManager.login_view. For example:
login_manager.login_view = "users.login"
The default message flashed is Please log in to access this page. To customize the message, set LoginManager.login_message:
login_manager.login_message = u"Bonvolu ensaluti por uzi tio paĝo."
To customize the message category, set LoginManager.login_message_category:
login_manager.login_message_category = "info"
When the log in view is redirected to, it will have a next variable in the query string, which is the page that the user was trying to access.
If you would like to customize the process further, decorate a function withLoginManager.unauthorized_handler:
@login_manager.unauthorized_handler
def unauthorized():
    # do stuff
    return a_response

Login using Authorization header

Caution
This method will be depreciated; use the request_loader below instead.
Sometimes you want to support Basic Auth login using the Authorization header, such as for api requests. To support login via header you will need to provide aheader_loader callback. This callback should behave the same as your user_loadercallback, except that it accepts a header value instead of a user id. For example:
@login_manager.header_loader
def load_user_from_header(header_val):
    header_val = header_val.replace('Basic ', '', 1)
    try:
        header_val = base64.b64decode(header_val)
    except TypeError:
        pass
    return User.query.filter_by(api_key=header_val).first()
By default the Authorization header’s value is passed to your header_loader callback. You can change the header used with the AUTH_HEADER_NAME configuration.

Custom Login using Request Loader

Sometimes you want to login users without using cookies, such as using header values or an api key passed as a query argument. In these cases, you should use therequest_loader callback. This callback should behave the same as your user_loadercallback, except that it accepts the Flask request instead of a user_id.
For example, to support login from both a url argument and from Basic Auth using the Authorization header:
@login_manager.request_loader
def load_user_from_request(request):

    # first, try to login using the api_key url arg
    api_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 Auth
    api_key = request.headers.get('Authorization')
    if api_key:
        api_key = api_key.replace('Basic ', '', 1)
        try:
            api_key = base64.b64decode(api_key)
        except TypeError:
            pass
        user = User.query.filter_by(api_key=api_key).first()
        if user:
            return user

    # finally, return None if both methods did not login the user
    return None

Anonymous Users

By default, when a user is not actually logged in, current_user is set to anAnonymousUserMixin object. It has the following properties:
  • is_active and is_authenticated return False
  • is_anonymous returns True
  • get_id returns None
If you have custom requirements for anonymous users (for example, they need to have a permissions field), you can provide a callable (either a class or factory function) that creates anonymous users to the LoginManager with:
login_manager.anonymous_user = MyAnonymousUser

Remember Me

“Remember Me” functionality can be tricky to implement. However, Flask-Login makes it nearly transparent - just pass remember=True to the login_user call. A cookie will be saved on the user’s computer, and then Flask-Login will automatically restore the user ID from that cookie if it is not in the session. The cookie is tamper-proof, so if the user tampers with it (i.e. inserts someone else’s user ID in place of their own), the cookie will merely be rejected, as if it was not there.
That level of functionality is handled automatically. However, you can (and should, if your application handles any kind of sensitive data) provide additional infrastructure to increase the security of your remember cookies.

Alternative Tokens

Using the user ID as the value of the remember token is not necessarily secure. More secure is a hash of the username and password combined, or something similar. To add an alternative token, add a method to your user objects:
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.
Correspondingly, you should set a token_loader function on the LoginManager, which takes a token (as stored in the cookie) and returns the appropriate User object.
The make_secure_token function is provided for creating auth tokens conveniently. It will concatenate all of its arguments, then HMAC it with the app’s secret key to ensure maximum cryptographic security. (If you store the user’s token in the database permanently, then you may wish to add random data to the token to further impede guessing.)
If your application uses passwords to authenticate users, including the password (or the salted password hash you should be using) in the auth token will ensure that if a user changes their password, their old authentication tokens will cease to be valid.

Fresh Logins

When a user logs in, their session is marked as “fresh,” which indicates that they actually authenticated on that session. When their session is destroyed and they are logged back in with a “remember me” cookie, it is marked as “non-fresh.”login_required does not differentiate between freshness, which is fine for most pages. However, sensitive actions like changing one’s personal information should require a fresh login. (Actions like changing one’s password should always require a password re-entry regardless.)
fresh_login_required, in addition to verifying that the user is logged in, will also ensure that their login is fresh. If not, it will send them to a page where they can re-enter their credentials. You can customize its behavior in the same ways as you can customize login_required, by setting LoginManager.refresh_view,needs_refresh_message, and 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_handler
def refresh():
    # do stuff
    return a_response
To mark a session as fresh again, call the confirm_login function.
Tag : Tutorials
0 Komentar untuk "Flask-Login"

Back To Top