-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enhance user authentication and security
Added email verification and password reset features. Implemented additional security measures including HTTPS enforcement, rate limiting on sensitive routes, and input validation to prevent common vulnerabilities. Improved user experience by introducing AJAX form submissions and user profile management.
- Loading branch information
Showing
5 changed files
with
83 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,10 +7,13 @@ | |
from app.main import main | ||
from app.auth import auth | ||
from app.models import User | ||
from flask_mail import Mail | ||
|
||
# Initialize the database | ||
db = SQLAlchemy() | ||
|
||
app = Flask(__name__) | ||
|
||
# For handling database migrations, Flask-Migrate is a useful extension that integrates with Flask and SQLAlchemy. | ||
migrate = Migrate(app, db) | ||
|
||
|
@@ -25,6 +28,13 @@ def load_user(user_id): | |
return User.query.get(int(user_id)) | ||
|
||
|
||
app.config['MAIL_SERVER'] = 'smtp.example.com' | ||
app.config['MAIL_PORT'] = 587 | ||
app.config['MAIL_USE_TLS'] = True | ||
app.config['MAIL_USERNAME'] = '[email protected]' | ||
app.config['MAIL_PASSWORD'] = secrets.token_urlsafe(16) | ||
mail = Mail(app) | ||
|
||
def create_app(config_class=Config): | ||
app = Flask(__name__) | ||
app.config.from_object(config_class) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from flask_wtf import FlaskForm | ||
from wtforms import StringField, PasswordField, SubmitField | ||
from wtforms.validators import DataRequired, EqualTo, ValidationError | ||
from yourapp.models import User | ||
|
||
class RegistrationForm(FlaskForm): | ||
username = StringField('Username', validators=[DataRequired()]) | ||
password = PasswordField('Password', validators=[DataRequired()]) | ||
confirm_password = PasswordField('Confirm Password', | ||
validators=[DataRequired(), EqualTo('password')]) | ||
submit = SubmitField('Sign Up') | ||
|
||
def validate_username(self, username): | ||
user = User.query.filter_by(username=username.data).first() | ||
if user: | ||
raise ValidationError('That username is taken. Please choose a different one.') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,20 @@ | ||
# models.py | ||
from app import db | ||
from flask_login import UserMixin | ||
from werkzeug.security import generate_password_hash | ||
|
||
class User(db.Model, UserMixin): | ||
id = db.Column(db.Integer, primary_key=True) | ||
username = db.Column(db.String(20), unique=True, nullable=False) | ||
email = db.Column(db.String(120), unique=True, nullable=False) | ||
password = db.Column(db.String(60), nullable=False) | ||
password_hash = db.Column(db.String(128) nullable=False) | ||
|
||
@property | ||
def password(self): | ||
raise AttributeError('password is not a readable attribute') | ||
|
||
@password.setter | ||
def password(self, password): | ||
self.password_hash = generate_password_hash(password) | ||
|
||
def verify_password(self, password): | ||
return check_password_hash(self.password_hash, password) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block content %} | ||
<div class="container"> | ||
<form method="post"> | ||
{{ form.hidden_tag() }} | ||
<div class="form-group"> | ||
{{ form.username.label }} | ||
{{ form.username(class="form-control") }} | ||
{% if form.username.errors %} | ||
{% for error in form.username.errors %} | ||
<div class="alert alert-danger">{{ error }}</div> | ||
{% endfor %} | ||
{% endif %} | ||
</div> | ||
<div class="form-group"> | ||
{{ form.password.label }} | ||
{{ form.password(class="form-control") }} | ||
</div> | ||
<div class="form-group"> | ||
{{ form.confirm_password.label }} | ||
{{ form.confirm_password(class="form-control") }} | ||
</div> | ||
<div class="form-group"> | ||
{{ form.submit(class="btn btn-primary") }} | ||
</div> | ||
</form> | ||
</div> | ||
{% endblock %} |