hack4impact/flask-base

View on GitHub
docs/account.md

Summary

Maintainability
Test Coverage
Routing (Account Routes)

This guide will be explaining the concept of routing by going through a file. We will be using `app/account/views.py`

## Login

```
@account.route('/login', methods=['GET', 'POST'])
def login():
    """Log in an existing user."""
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data).first()
        if user is not None and user.password_hash is not None and \
                user.verify_password(form.password.data):
            login_user(user, form.remember_me.data)
            flash('You are now logged in. Welcome back!', 'success')
            return redirect(request.args.get('next') or url_for('main.index'))
        else:
            flash('Invalid email or password.', 'form-error')
    return render_template('account/login.html', form=form)
```
All routes are decorated with the name of the associated Blueprint along
with the .route prop with attributes of (name, methods=[]). For example
`@account.route('/login', method=['GET', 'POST'])` creates a route accessible
at `yourdomain.com/account/login`.

This route can accept either `POST` or `GET`
requests which is appropriate since there is a form associated with the
login process. This form is loaded from the forms.py file (in this case
the `LoginForm()` is loaded) and we then check if the form is valid
(`validate_on_submit`) in that it is a valid POST request.
We grab the form field named 'email' and query the User database for the
user that has that email. Then we call the `verify_password` method
from the User class for this specific user instance and check the hashed
password in the database against the password provided by the user which
is hashed with the SECRET_KEY. If everything is fine, the Flask-login
extendion performs a login_user action and sets the `SESSION['user_id']`
equivalent to the user id provided from the user instance. If the
form has remember_me set to True (ie checked) then that is passed along
as a parameter in login_user.

If it was redirected to this /login page, their URL will have a parameter
called `next` containing the URL they need to be directed to after they
login. Otherwise, they will just be sent to the main.index route
This is true for the admin as well. It is best to edit this functionality
since index pages should differ by user type. There is a flash sent as well
if the request is successful.

If there is an error in the user checking process, then the user is kicked
back to the account/login page with a flashed form error.

If this is a GET request, only the account/login page is rendered

## Logout

```
@account.route('/logout')
@login_required
def logout():
    logout_user()
    flash('You have been logged out.', 'info')
    return redirect(url_for('main.index'))
```

The Flask-login Manager has a built in logout_user function that
removes the SESSION variables from the user's browser and logs out
the user completely