- Пользователь входит в систему и перенаправляется на домашнюю страницу, где информация о пользователе загружается из API и сохраняется.
- Получение 401 из API на домашней странице
Пока я тестировал свою систему в разработке, проблем не возникло. однако после развертывания в Heroku (я также пробовал использовать PythonAnywhere) возникла одна проблема. После входа в систему я получаю статус 200: вход успешно выполнен, но после того, как пользователь перенаправляется на домашнюю страницу, я получаю ошибку 401 от моего API, сообщающую, что пользователь не вошел в систему.
Что я пробовал до сих пор:
- Использование типа сеанса SQLAlchemy и подключение к моей базе данных для сохранения состояния сеанса
Добавление домена cookie сеанса - Использование Flask-session
- Добавление Flask-tailsman для обеспечения соблюдения HTTPS
- Проверка настроек CORS и убедитесь, что включены все домены.
- Убедитесь, что user_loader в порядке.
- Использование приложения web: Gunicorn: app --preload в файле Procfile
Журналы Heroku:
Скриншот журналов Heroku
Код (миниатюрный):< /p>
- create_app.py
Код: Выделить всё
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from flask_session import Session
import os
from flask_talisman import Talisman
# Sets up SQLAlchemy database
db = SQLAlchemy()
# Creates flask app
def create_app():
app = Flask(
__name__,
static_url_path="",
static_folder="../client/build",
template_folder="build",
) # Initializes flask app
CORS(app, origins=["", "", "", "", "", ""])
app.config[
"SQLALCHEMY_DATABASE_URI"
] = "mysql+pymysql://"
app.config["SECRET_KEY"] = os.getenv("SECRET_KEY") # Secret key for flask app
app.config["UPLOAD_FOLDER"] = "static/images"
app.config['CORS_LOGGING'] = True
db.init_app(app)
app.config["SESSION_TYPE"] = "sqlalchemy"
app.config["SESSION_SQLALCHEMY"] = db # the SQLAlchemy object you have already created
Session(app)
app.config['SESSION_COOKIE_DOMAIN'] = '.'
return app
# Initializes flask app for use in other files
app = create_app()
Talisman(app)
Код: Выделить всё
from flask import request, Blueprint
from flask_login import (
LoginManager,
current_user,
login_required,
)
from PIL import Image
from server_module.create_app import app, db, limiter
from server_module.models import User
import uuid
# Sets up login manager
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "loginUser"
# User loader
@login_manager.user_loader
def load_user(id):
user = User.query.get(id)
return user
# Handles unauthorized access
@login_manager.unauthorized_handler
def unauthorized_handler():
return "Unauthorized", 401
# Loads user
login_manager.user_loader(load_user)
Код: Выделить всё
class User(db.Model, UserMixin, SerializerMixin):
# These define columns of the User table
id = db.Column(
db.String(40),
primary_key=True,
nullable=False,
default=lambda: str(uuid.uuid4()),
)
username = db.Column(db.String(150), nullable=False, unique=True, index=True)
email = db.Column(db.String(150), nullable=False, unique=True)
password = db.Column(db.String(500), nullable=False)
created = db.Column(
db.DateTime(timezone=True), server_default=func.now(), nullable=False
)
type = db.Column(db.String(15), default="student", nullable=False, index=True)
avatar = db.Column(db.String(200), default="default", nullable=False)
status = db.Column(db.String(20), default="active", nullable=False)
def __init__(self, username, email, password, type, fullname, avatar="default"):
self.username = username
self.email = email
self.type = type
self.avatar = avatar
self.password = generate_password_hash(password=password)
self.fullName = fullname
Код: Выделить всё
# The login API
@users_blueprint.route("/login", methods=["POST"]) # Completed
def loginUser():
"""
Login user
- Parameters required:
- password: string (min 6 characters, atleast one number and one special character)
- email: string (valid email, max 150 characters, min 5 characters)
- token: string (recaptcha token)
"""
try:
try:
data = request.get_json()
except:
return error_msg()
if not all(key in data for key in ("password", "email")):
return error_msg()
user = User.query.filter_by(email=data["email"]).first()
if not user:
return error_msg(404)
if not check_password_hash(user.password, data["password"]):
return {"msg": "Incorrect password"}, 400
login_user(user, remember=True) # Logs user in
return {"msg": "User logged in successfully"}, 200
except Exception as e:
print("An error occurred: ", e)
return error_msg(500, e)
Подробнее здесь: https://stackoverflow.com/questions/781 ... production