Anonymous 13654
---
### **Description:**
I'm building a Flask application with user login functionality using Flask-WTF for form handling and Flask-Login for user authentication. However, I am unable to log in successfully. The page does not redirect as expected, and the login validation does not work.
I have implemented CSRF protection, and I believe the issue might be with how the data is being validated or how the routes are configured.
---
### **What I've Tried:**
1. Ensured that I am redirecting using `url_for()` to a valid route.
2. Added `csrf.init_app(app)` in my `create_app()` function.
3. Included `{{ form.csrf_token() }}` in my login form.
4. Verified that my database connection works, and user data is stored correctly.
5. Checked that Flask-Login's `login_user()` function is being called.
---
### **Code Snippets:**
#### `__init__.py`
```python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from flask_wtf.csrf import CSRFProtect
db = SQLAlchemy()
migrate = Migrate()
bcrypt = Bcrypt()
login_manager = LoginManager()
csrf = CSRFProtect()
def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:Root1234!@localhost/school_hub'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.secret_key = 'your-secret-key'
db.init_app(app)
migrate.init_app(app, db)
login_manager.init_app(app)
bcrypt.init_app(app)
csrf.init_app(app)
login_manager.login_view = 'login'
from .routes import main as main_blueprint
app.register_blueprint(main_blueprint)
with app.app_context():
db.create_all()
return app
@login_manager.user_loader
def load_user(user_id):
from .models import User
return User.query.get(int(user_id))
```
#### `routes.py`
```python
from flask import render_template, request, redirect, url_for, flash
from flask_login import login_user
from .models import User
from .forms import LoginForm
@app.route("/login", methods=["GET", "POST"])
def login():
form = LoginForm()
if form.validate_on_submit():
email = form.email.data
password = form.password.data
user = User.query.filter_by(email=email).first()
if user and user.check_password(password):
login_user(user)
return redirect(url_for('home'))
else:
flash("Invalid credentials", "danger")
return render_template("login.html", form=form)
```
#### `login.html`
```html
<form action="" method="POST">
{{ form.csrf_token() }}
{{ form.email.label() }}
{{ form.email() }}
<br>
{{ form.password.label() }}
{{ form.password() }}
<br>
{{ form.submit() }}
</form>
```
#### `forms.py`
```python
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email
class LoginForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Login')
```
#### `models.py`
```python
from . import db, bcrypt
from flask_login import UserMixin
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True, nullable=False)
password = db.Column(db.String(150), nullable=False)
def check_password(self, password):
return bcrypt.check_password_hash(self.password, password)
```
---
### **Error Messages:**
1. No error appears, but the login fails.
2. Sometimes I get `Invalid credentials` even though the credentials are correct.
---
### **Expected Behavior:**
When a user enters valid credentials, they should be logged in and redirected to the homepage.
---
### **Environment:**
- Flask 2.x
- Flask-WTF
- Flask-SQLAlchemy
- MySQL
- Python 3.12
---
### **What I Need Help With:**
1. Debugging why the login fails.
2. Ensuring the redirection works as expected after login.
3. Any best practices I might be missing.
---