[PYTHON] SNS made with Flask Flask (login process by flask_login)

TL;DL Udemy attendance record for the following courses

Web application development course with Python + Flask! !! ~ Master Flask from 0 to create SNS ~ https://www.udemy.com/course/flaskpythonweb/

This article describes the login process with Flask_login.

flask_login A library that allows you to easily implement login processing in Flask applications https://flask-login.readthedocs.io/en/latest/

Folder structure

login_sample ├── flaskr │   ├── __init__.py │   ├── forms.py │   ├── models.py │   ├── templates │   │   ├── _formhelpers.html │   │   ├── base.html │   │   ├── home.html │   │   ├── login.html │   │   ├── register.html │   │   ├── user.html │   │   └── welcome.html │   └── views.py └── setup.py

Library installation

(flaskenv) (base) root@e8cf64ce12e9:/home/venv/flaskenv/login_sample# pip install flask_login

code

__init__.py

-Register the login processing method in "login_maneager.login_view". Here, since the application name is set to "app" in Blueprint, it will be "app.login". -Register the flash message to be displayed when redirected to "login_manager.login_message". If not specified, the default message will be used. -When using LoginManager, initialize it with the "login_manager.init_app ([name])" method and register the application.

import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager

# Flask-The process of connecting Login and Flask application.
login_manager = LoginManager()
#Process executed when logging in Application name.login
login_manager.login_view = 'app.login'
#Message displayed when redirected to login screen
login_manager.login_message = 'Please login'

base_dir = os.path.abspath(os.path.dirname(__name__))
#db creation
db = SQLAlchemy()
#Create an instance for Migration
migrate = Migrate()

def create_app():
    #Flask application creation
    app = Flask(__name__)

    #DB definition
    app.config['SECRET_KEY'] = 'mysite'
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + \
        os.path.join(base_dir, 'data.sqlite')
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

    #Register the Blueprint object in the app
    from flaskr.views import bp
    app.register_blueprint(bp)

    #Initialize an application that uses DB
    db.init_app(app)

    #Initialize the flask app and DB to migrate
    migrate.init_app(app, db)

    #Initialize loginManager
    login_manager.init_app(app)
    return app

views.py -By attaching the "@login_required" decorator, check if you are logged in before executing the corresponding method, and if you are not logged in, the method will not be executed and login_manager. In \ _ \ _ init \ _ \ _.py. Execute the method defined in login_view. -Execute login processing by passing the user name to the login_user function. By passing remember = True as the second argument, session information can be left even if the browser is closed. -In the "request.args.get ('next')" method, you can get the route specified as the transition destination on the request source screen. This makes it possible to transition to the intended screen without directly respecifying the transition destination.

from flask import Blueprint, request, render_template, redirect, url_for
from flask_login import login_user, login_required, logout_user
from flaskr.forms import LoginForm, RegisterForm
from flaskr.models import User

bp = Blueprint('app', __name__, url_prefix='')

@bp.route('/')
def home():
    return render_template('home.html')

# login_due to required, login_If user is not executed, the following functions will not be executed.
#If you are not logged in__init__.py login_Transition to the process specified in view.
@bp.route('/welcome')
@login_required
def welcome():
    return render_template('welcome.html')

@bp.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm(request.form)
    if request.method == 'POST' and form.validate():
        user = User.select_by_email(form.email.data)

        if user and user.validate_password(form.password.data):
            # login_Execute login process by passing the user name to the user function.
            # remember=By setting it to True, it is possible to leave session information even if the browser is closed.
            login_user(user, remember=True)
            #The process that called this login method specified it as the original transition destination.
            #page(url)To get.
            next = request.args.get('next')
            if not next:
                next = url_for('app.welcome')

            return redirect(next)
    return render_template('login.html', form=form)

models.py point -Confirm that you are a logged-in user by acquiring and returning the user ID with the load_user method with the "@ login_manager.user_loader" decorator. The user information (user object) returned by this process is the "current_user" used in home.html. -UserMixin is a class that summarizes what is required by flask-login, and must be inherited when class is defined.

from flaskr import db, login_manager  # __init__.Imported from py
from flask_bcrypt import generate_password_hash, check_password_hash
from flask_login import UserMixin

#Called by template to return the logged-in user stored in the session.
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(user_id)

#User Mixin is Flask-Definition of objects required for users who use Login
class User(UserMixin, db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, index=True)
    username = db.Column(db.String(64), index=True)
    password = db.Column(db.String(128))

    def __init__(self, email, username, password):
        self.email = email
        self.username = username
        self.password = generate_password_hash(password)

    def validate_password(self, password):
        return check_password_hash(self.password, password)

    def add_user(self):
        with db.session.begin(subtransactions=True):
            db.session.add(self)
        db.session.commit()

    @classmethod
    def select_by_email(cls, email):
        return cls.query.filter_by(email=email).first()

login.html

{% from "_formhelpers.html" import render_field %}
{% extends "base.html" %}
{% block content %}
<!-- get_flashed_messages()Display a message when redirected with.
The message to be displayed is__init__.py login_manager.login_Defined in message-->
{% for message in get_flashed_messages() %}
    {{ message }}
{% endfor%}
<form method='POST'>
    {{ form.csrf_token }}
    {{ render_field(form.email) }}
    {{ render_field(form.password) }}
    {{ form.submit()}}
</form>
{% endblock %}

home.html

{% extends 'base.html' %}
{% block content %}
<div>
    {% if current_user.is_authenticated %}
    <p>Logind{{ current_user.username }}</p>
    {% else %}
    <p>Please log in or register.</p>
    {% endif %}
</div>
{% endblock %}

Recommended Posts

SNS made with Flask Flask (login process by flask_login)
SNS Python basics made with Flask
SNS made with Flask Flask (Blueprint, bcrypt)
Twitter posting client made with Flask with simple login function
[LINE login] Verify state with Flask
I made a Mattermost bot with Python (+ Flask)
I made a login / logout process using Python Bottle.
Full-scale server made with Nginx + uWSGI + Flask + Ubuntu (installation)
Full-scale server made with Nginx + uWSGI + Flask + Ubuntu (implementation)