Автор оригинала: Pankaj Kumar.
В этой статье мы будем кодировать аутентификацию пользователя Flask с помощью библиотеки Flask-Login и SQLAlchemy. Так что давайте начнем!
В настоящее время почти на всех веб-сайтах закодированы системы аутентификации пользователей. Мы можем настроить учетную запись с аутентификацией пользователя либо напрямую, либо через стороннюю организацию, такую как Google, Facebook. Яблоко и т. Д.
Типичная страница входа пользователя выглядит следующим образом:
Аутентификация пользователя является важной частью веб-страницы, поскольку она защищает пользовательские данные таким образом, что только этот конкретный пользователь может получить к ним доступ. Существуют различные способы аутентификации пользователя:
- Аутентификация на основе файлов cookie
- аутентификация на основе токенов
- Аутентификация OAuth
- OpenID
- Saml
Теперь мы будем кодировать с использованием аутентификации Flask-Login. Итак, давайте погрузимся в часть кодирования.
Практическая работа с аутентификацией пользователя Flask
Flask-login использует аутентификацию на основе файлов cookie. Когда клиент входит в систему с помощью своих учетных данных, Flask создает сеанс, содержащий идентификатор пользователя , а затем отправляет идентификатор сеанса пользователю через файл cookie, с помощью которого он может входить и выходить по мере необходимости.
Сначала нам нужно установить Flask-Login
pip install flask-login
Теперь, когда он установлен, давайте перейдем к части кодирования!
1. Кодирование models.py файл
Во-первых, мы создадим Модель пользователя для хранения учетных данных пользователя. Для этого мы будем использовать базу данных Flask_SQLAlchemy и SQLite.
Здесь важно отметить, что мы не можем сохранить пароли пользователей непосредственно в базе данных, потому что, если какой-то хакер получит доступ к нашему сайту, он сможет получить всю информацию из базы данных.
Поэтому мы не можем себе этого позволить. Но не волнуйтесь, Flask werkzeug имеет встроенные функции для решения этой проблемы.
1.1 Настройка хэша пароля
Решение состоит в том, чтобы использовать Хэш пароля . Давайте посмотрим, что такое хэш, поэтому перейдите в оболочку python в терминале и выполните команду
from werkzeug.security import generate_password_hash a = generate_password_hash('1234') print(a)
Мы получим длинную случайную строку, как показано ниже:
Следовательно, даже если хакер получит к ним доступ, он не сможет их расшифровать. Кроме того, у нас есть еще одна функция для сравнения хэша с паролем, называемая check_password_hash .
Он работает, как показано ниже:
from werkzeug.security import generate_password_hash, check_password_hash a = generate_password_hash('1234') print(a) chech_password_hash(a,'1234')
Теперь нажмите enter, он вернет True при совпадении и False при несоответствии.
1.2 Добавление хэшированных паролей в базу данных
Кроме того , если у вас нет Flask SQLAlchemy, просто установите его с помощью команды pip:
pip install flask-sqlalchemy
Хорошо, теперь, когда SQLAlchemy на месте, создайте файл models.py и добавьте код:
from flask_sqlalchemy import SQLAlchemy from werkzeug.security import generate_password_hash, check_password_hash from flask_login import UserMixin db = SQLAlchemy() class UserModel(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(80), unique=True) username = db.Column(db.String(100)) password_hash = db.Column(db.String()) def set_password(self,password): self.password_hash = generate_password_hash(password) def check_password(self,password): return check_password_hash(self.password_hash,password)
Здесь:
- Мы храним email , имя пользователя, и хэш пароля
- Кроме того, мы определим 2 метода класса – set_password для генерации хэша пароля и check_password для их сравнения
Мы также используем UserMixin из библиотеки flask_login. UserMixin имеет некоторые встроенные функции, которые мы будем использовать позже:
- is_authenticated: Return True если у пользователя есть действительные учетные данные
- is_active: Возвращает True , если учетная запись пользователя активна. Например – Все отключенные аккаунты в Instagram вернутся False.
- is_anonymous: Возвращает False для обычных пользователей и True для новичков/анонимных пользователей
- get_id(): Возвращает уникальный идентификатор пользователя в виде строки.
1.3. Установка расширения Flask_login
Кроме того, нам нужно создать и инициализировать расширение Flask_login. Мы делаем это с помощью кода:
from flask_login import LoginManager #... login = LoginManager() #...
Как мы обсуждали ранее, Flask хранит Идентификатор пользователя вошедших в сеанс пользователей. Поскольку Flask_Login ничего не знает о базах данных, нам нужно создать функцию для их связи.
Это делается с помощью функции user_loader . Синтаксис таков:
from flask_login import LoginManager login = LoginManager() @login.user_loader def load_user(id): return UserModel.query.get(int(id))
1.4. Полный код
Вот и все с models.py часть. Давайте просто взглянем на весь код один раз:
from flask_sqlalchemy import SQLAlchemy from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash from flask_login import LoginManager login = LoginManager() db = SQLAlchemy() class UserModel(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(80), unique=True) username = db.Column(db.String(100)) password_hash = db.Column(db.String()) def set_password(self,password): self.password_hash = generate_password_hash(password) def check_password(self,password): return check_password_hash(self.password_hash,password) @login.user_loader def load_user(id): return UserModel.query.get(int(id))
Пожалуйста, ознакомьтесь с нашей статьей SQLAlchemy, если вы не знакомы с Flask SQLAlchemy.
2. Кодирование нашего основного файла приложения колбы
Теперь давайте закодируем наш основной файл приложения Flask.
from flask import Flask app =Flask(__name__) app.run(host='localhost', port=5000)
2.1 Привязка базы данных к нашему Флэш-файлу
Хорошо, теперь нам нужно связать нашу базу данных SQLite с SQLAlchemy. Так что для этого добавьте код:
from flask import Flask app =Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.run(host='localhost', port=5000)
Просто замените любым именем, которое вы хотите. Кроме того, нам нужно связать наш экземпляр базы данных SQLAlchemy (присутствует в models.py файл) с основным приложением. Для этого добавьте:
from flask import Flask from models import db app =Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db.init_app(app) app.run(host='localhost', port=5000)
Теперь мы должны добавить код для создания файла базы данных до первого запроса пользователя. Мы делаем это следующим образом:
from flask import Flask from models import db app =Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db.init_app(app) @app.before_first_request def create_table(): db.create_all() app.run(host='localhost', port=5000)
Теперь все, что связано с частью БД, закончилось. Давайте теперь перейдем к части Flask_login
2.2 Добавление аутентификации пользователя в наше приложение
Как и в случае с экземпляром БД, мы также должны связать экземпляр login с нашим приложением. Мы делаем это с помощью:
from flask import Flask from models import login app =Flask(__name__) login.init_app(app) app.run(host='localhost', port=5000)
После этого мы сообщаем Flask_login о странице; не прошедшие проверку пользователи будут перенаправлены, что будет ничем иным, как самой страницей входа.
Поэтому добавьте код:
from flask import Flask from models import login app =Flask(__name__) login.init_app(app) login.login_view = 'login' app.run(host='localhost', port=5000)
После упоминания страницы перенаправления мы можем просто добавить @login_required декоратор ко всем представлениям веб-страниц, для которых потребуется аутентификация.
Круто! Теперь осталось только войти, зарегистрироваться и выйти из системы |/представления. Но перед этим давайте закодируем простую страницу, которую пользователи смогут увидеть после аутентификации
2.3 Кодирование простого представления
Поэтому добавьте простой вид:
from flask import Flask, render_template from flask_login import login_required @app.route('/blogs') @login_required def blog(): return render_template('blog.html')
Обратите внимание, как мы использовали @login_required декоратор. В blog.html шаблон будет:
Welcome to the Blog
Hi {{ current_user.username }}
Logout Here
Ознакомьтесь с нашей статьей о шаблонах Flash, чтобы узнать больше о шаблонах.
2.3 Кодирование представления входа в систему
Представление входа в систему будет простым. Он должен сделать следующее:
- Если пользователь уже прошел аутентификацию, перенаправьте его на страницу блогов или отобразите HTML-форму
- Извлечение информации о пользователе из базы данных
- Сравните учетные данные, если они верны, перенаправьте на страницу блогов
Поэтому добавьте код:
from flask import Flask, request, render_template from flask_login import current_user, login_user @app.route('/login', methods = ['POST', 'GET']) def login(): if current_user.is_authenticated: return redirect('/blogs') if request.method == 'POST': email = request.form['email'] user = UserModel.query.filter_by(email = email).first() if user is not None and user.check_password(request.form['password']): login_user(user) return redirect('/blogs') return render_template('login.html')
И login.html шаблон:
2.4 Кодирование представления регистра
Представление реестра должно быть в состоянии выполнять следующие действия:
- если пользователь уже прошел аутентификацию, перенаправьте его на страницу блогов или отобразите HTML-форму
- Добавьте пользовательские данные в базу данных
- Перенаправление на страницу входа в систему
Таким образом, код будет:
from flask import Flask, request, render_template from flask_login import current_user @app.route('/register', methods=['POST', 'GET']) def register(): if current_user.is_authenticated: return redirect('/blogs') if request.method == 'POST': email = request.form['email'] username = request.form['username'] password = request.form['password'] if UserModel.query.filter_by(email=email): return ('Email already Present') user = UserModel(email=email, username=username) user.set_password(password) db.session.add(user) db.session.commit() return redirect('/login') return render_template('register.html')
Поэтому register.html страница будет:
2.5 Кодирование представления выхода из системы
Представление выхода из системы должно просто выводить пользователей из системы. Поэтому добавьте код:
from flask import Flask, render_template from Flask_login import logout_user @app.route('/logout') def logout(): logout_user() return redirect('/blogs')
Вот и все !! Поэтому давайте еще раз взглянем на полный код этого раздела:
from flask import Flask,render_template,request,redirect from flask_login import login_required, current_user, login_user, logout_user from models import UserModel,db,login app = Flask(__name__) app.secret_key = 'xyz' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db.init_app(app) login.init_app(app) login.login_view = 'login' @app.before_first_request def create_all(): db.create_all() @app.route('/blogs') @login_required def blog(): return render_template('blog.html') @app.route('/login', methods = ['POST', 'GET']) def login(): if current_user.is_authenticated: return redirect('/blogs') if request.method == 'POST': email = request.form['email'] user = UserModel.query.filter_by(email = email).first() if user is not None and user.check_password(request.form['password']): login_user(user) return redirect('/blogs') return render_template('login.html') @app.route('/register', methods=['POST', 'GET']) def register(): if current_user.is_authenticated: return redirect('/blogs') if request.method == 'POST': email = request.form['email'] username = request.form['username'] password = request.form['password'] if UserModel.query.filter_by(email=email).first(): return ('Email already Present') user = UserModel(email=email, username=username) user.set_password(password) db.session.add(user) db.session.commit() return redirect('/login') return render_template('register.html') @app.route('/logout') def logout(): logout_user() return redirect('/blogs')
Модель пользователя .query.filter_by(электронная почта=электронная почта).first() вернет первого пользователя, которого он получит из базы данных, или вернет None , если пользователь не был найден.
Реализация приложения аутентификации пользователя Flask
Давайте, наконец, протестируем наше приложение. Запустите файл Flash:
python filename.py
И попробуйте зайти в ” /блоги “. Вы будете перенаправлены на страницу login .
Нажмите на кнопку зарегистрироваться, а затем добавьте свои данные.
Нажмите кнопку отправить, и вы вернетесь на страницу входа в систему. На этот раз введите свои учетные данные и войдите в систему. Вы увидите страницу блогов !!
Примечание: Использование простых электронных писем, таких как a@gmail.com может привести к ошибке, подобной той, что показана ниже в браузере Chrome.
Как вы можете видеть, мы были перенаправлены на конечную точку “блоги” здесь. На моем скриншоте выше появилось сообщение безопасности, так как я использовал случайный несуществующий пароль с очень слабым паролем.
Вы можете попробовать то же самое с более надежным паролем и хорошим адресом электронной почты, и вы сразу увидите страницу блогов, а не предупреждение о безопасности, как в данном случае.
Вывод
Вот и все, ребята! Все дело было в аутентификации пользователя в Flask. Ознакомьтесь с нашей статьей о сеансах колбы и файлах cookie, чтобы узнать больше о том, как они работают.
В следующей статье мы развернем наше приложение на облачном сервере.