-
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.
- Loading branch information
1 parent
ae3e45a
commit a4fad23
Showing
13 changed files
with
385 additions
and
1 deletion.
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 |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Python | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
*.so | ||
.Python | ||
env/ | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
|
||
# Flask | ||
instance/ | ||
.webassets-cache | ||
app.db | ||
|
||
# Virtual Environment | ||
venv/ | ||
ENV/ | ||
|
||
# IDE | ||
.idea/ | ||
.vscode/ | ||
*.swp | ||
*.swo | ||
|
||
# OS | ||
.DS_Store | ||
Thumbs.db |
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 +1,63 @@ | ||
# docs-flask-simple-app | ||
# Flask Authentication Project | ||
|
||
A simple Flask application demonstrating authentication, SQLAlchemy ORM, and a REST API. | ||
|
||
## Features | ||
|
||
- User authentication (login/register/logout) | ||
- Public and protected routes | ||
- SQLite database with SQLAlchemy ORM | ||
- REST API endpoint for users | ||
- Bootstrap-styled templates | ||
|
||
## Installation | ||
|
||
1. Create a virtual environment: | ||
```bash | ||
python -m venv venv | ||
``` | ||
|
||
2. Activate the virtual environment: | ||
- Windows: | ||
```bash | ||
venv\Scripts\activate | ||
``` | ||
- Unix or MacOS: | ||
```bash | ||
source venv/bin/activate | ||
``` | ||
|
||
3. Install requirements: | ||
```bash | ||
pip install -r requirements.txt | ||
``` | ||
|
||
4. Run the application: | ||
```bash | ||
python run.py | ||
``` | ||
|
||
## Routes | ||
|
||
- `/` - Public homepage | ||
- `/private` - Protected route (requires login) | ||
- `/api/users` - API endpoint listing all users | ||
- `/login` - User login | ||
- `/register` - User registration | ||
- `/logout` - User logout | ||
|
||
## API Usage | ||
|
||
Get list of all users: | ||
```bash | ||
curl http://localhost:5000/api/users | ||
``` | ||
|
||
## Security Note | ||
|
||
This is a demonstration project. In a production environment, you should: | ||
- Use a proper secret key | ||
- Enable HTTPS | ||
- Implement proper password validation | ||
- Add rate limiting | ||
- Use environment variables for sensitive data |
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,24 @@ | ||
from flask import Flask | ||
from flask_sqlalchemy import SQLAlchemy | ||
from flask_login import LoginManager | ||
from app.config import Config | ||
|
||
db = SQLAlchemy() | ||
login_manager = LoginManager() | ||
login_manager.login_view = 'auth.login' | ||
|
||
def create_app(): | ||
app = Flask(__name__) | ||
app.config.from_object(Config) | ||
|
||
db.init_app(app) | ||
login_manager.init_app(app) | ||
|
||
from app.routes import main, auth | ||
app.register_blueprint(main) | ||
app.register_blueprint(auth) | ||
|
||
with app.app_context(): | ||
db.create_all() | ||
|
||
return app |
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,4 @@ | ||
class Config: | ||
SECRET_KEY = 'your-secret-key-here' # Change this to a secure secret key | ||
SQLALCHEMY_DATABASE_URI = 'sqlite:///app.db' | ||
SQLALCHEMY_TRACK_MODIFICATIONS = False |
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,18 @@ | ||
from flask_login import UserMixin | ||
from werkzeug.security import generate_password_hash, check_password_hash | ||
from app import db, login_manager | ||
|
||
class User(UserMixin, db.Model): | ||
id = db.Column(db.Integer, primary_key=True) | ||
username = db.Column(db.String(64), unique=True, nullable=False) | ||
password_hash = db.Column(db.String(128)) | ||
|
||
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_manager.user_loader | ||
def load_user(id): | ||
return User.query.get(int(id)) |
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,61 @@ | ||
from flask import Blueprint, render_template, redirect, url_for, request, jsonify | ||
from flask_login import login_user, logout_user, login_required, current_user | ||
from app.models import User, db | ||
|
||
main = Blueprint('main', __name__) | ||
auth = Blueprint('auth', __name__) | ||
|
||
# Public homepage route | ||
@main.route('/') | ||
def home(): | ||
return render_template('home.html') | ||
|
||
# Protected route | ||
@main.route('/private') | ||
@login_required | ||
def private(): | ||
return render_template('private.html') | ||
|
||
# API route to list users | ||
@main.route('/api/users') | ||
def list_users(): | ||
users = User.query.all() | ||
return jsonify([{'id': user.id, 'username': user.username} for user in users]) | ||
|
||
# Authentication routes | ||
@auth.route('/login', methods=['GET', 'POST']) | ||
def login(): | ||
if request.method == 'POST': | ||
username = request.form.get('username') | ||
password = request.form.get('password') | ||
user = User.query.filter_by(username=username).first() | ||
|
||
if user and user.check_password(password): | ||
login_user(user) | ||
return redirect(url_for('main.private')) | ||
|
||
return render_template('login.html') | ||
|
||
@auth.route('/register', methods=['GET', 'POST']) | ||
def register(): | ||
if request.method == 'POST': | ||
username = request.form.get('username') | ||
password = request.form.get('password') | ||
|
||
if User.query.filter_by(username=username).first(): | ||
return "Username already exists" | ||
|
||
user = User(username=username) | ||
user.set_password(password) | ||
db.session.add(user) | ||
db.session.commit() | ||
|
||
return redirect(url_for('auth.login')) | ||
|
||
return render_template('register.html') | ||
|
||
@auth.route('/logout') | ||
@login_required | ||
def logout(): | ||
logout_user() | ||
return redirect(url_for('main.home')) |
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,62 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>{% block title %}{% endblock %} - Flask App</title> | ||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"> | ||
</head> | ||
<body> | ||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4"> | ||
<div class="container"> | ||
<a class="navbar-brand" href="{{ url_for('main.home') }}">Flask App</a> | ||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"> | ||
<span class="navbar-toggler-icon"></span> | ||
</button> | ||
<div class="collapse navbar-collapse" id="navbarNav"> | ||
<ul class="navbar-nav me-auto"> | ||
<li class="nav-item"> | ||
<a class="nav-link" href="{{ url_for('main.home') }}">Home</a> | ||
</li> | ||
{% if current_user.is_authenticated %} | ||
<li class="nav-item"> | ||
<a class="nav-link" href="{{ url_for('main.private') }}">Private</a> | ||
</li> | ||
{% endif %} | ||
</ul> | ||
<ul class="navbar-nav"> | ||
{% if current_user.is_authenticated %} | ||
<li class="nav-item"> | ||
<span class="nav-link">Welcome, {{ current_user.username }}!</span> | ||
</li> | ||
<li class="nav-item"> | ||
<a class="nav-link" href="{{ url_for('auth.logout') }}">Logout</a> | ||
</li> | ||
{% else %} | ||
<li class="nav-item"> | ||
<a class="nav-link" href="{{ url_for('auth.login') }}">Login</a> | ||
</li> | ||
<li class="nav-item"> | ||
<a class="nav-link" href="{{ url_for('auth.register') }}">Register</a> | ||
</li> | ||
{% endif %} | ||
</ul> | ||
</div> | ||
</div> | ||
</nav> | ||
|
||
<div class="container"> | ||
{% with messages = get_flashed_messages(with_categories=true) %} | ||
{% if messages %} | ||
{% for category, message in messages %} | ||
<div class="alert alert-{{ category }}">{{ message }}</div> | ||
{% endfor %} | ||
{% endif %} | ||
{% endwith %} | ||
|
||
{% block content %}{% endblock %} | ||
</div> | ||
|
||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> | ||
</body> | ||
</html> |
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,23 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block title %}Home{% endblock %} | ||
|
||
{% block content %} | ||
<div class="row justify-content-center"> | ||
<div class="col-md-8"> | ||
<div class="card"> | ||
<div class="card-body"> | ||
<h1 class="card-title">Welcome to Flask App</h1> | ||
<p class="card-text">This is a public page that anyone can access.</p> | ||
{% if not current_user.is_authenticated %} | ||
<p class="card-text"> | ||
<a href="{{ url_for('auth.login') }}" class="btn btn-primary">Login</a> or | ||
<a href="{{ url_for('auth.register') }}" class="btn btn-success">Register</a> | ||
to access private content. | ||
</p> | ||
{% endif %} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
{% endblock %} |
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,31 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block title %}Login{% endblock %} | ||
|
||
{% block content %} | ||
<div class="row justify-content-center"> | ||
<div class="col-md-6"> | ||
<div class="card"> | ||
<div class="card-body"> | ||
<h2 class="card-title text-center mb-4">Login</h2> | ||
<form method="POST"> | ||
<div class="mb-3"> | ||
<label for="username" class="form-label">Username</label> | ||
<input type="text" class="form-control" id="username" name="username" required> | ||
</div> | ||
<div class="mb-3"> | ||
<label for="password" class="form-label">Password</label> | ||
<input type="password" class="form-control" id="password" name="password" required> | ||
</div> | ||
<div class="d-grid"> | ||
<button type="submit" class="btn btn-primary">Login</button> | ||
</div> | ||
</form> | ||
<p class="text-center mt-3"> | ||
Don't have an account? <a href="{{ url_for('auth.register') }}">Register here</a> | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
{% endblock %} |
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,17 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block title %}Private Page{% endblock %} | ||
|
||
{% block content %} | ||
<div class="row justify-content-center"> | ||
<div class="col-md-8"> | ||
<div class="card"> | ||
<div class="card-body"> | ||
<h1 class="card-title">Private Page</h1> | ||
<p class="card-text">Welcome to the private page, {{ current_user.username }}!</p> | ||
<p class="card-text">This content is only visible to authenticated users.</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
{% endblock %} |
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,31 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block title %}Register{% endblock %} | ||
|
||
{% block content %} | ||
<div class="row justify-content-center"> | ||
<div class="col-md-6"> | ||
<div class="card"> | ||
<div class="card-body"> | ||
<h2 class="card-title text-center mb-4">Register</h2> | ||
<form method="POST"> | ||
<div class="mb-3"> | ||
<label for="username" class="form-label">Username</label> | ||
<input type="text" class="form-control" id="username" name="username" required> | ||
</div> | ||
<div class="mb-3"> | ||
<label for="password" class="form-label">Password</label> | ||
<input type="password" class="form-control" id="password" name="password" required> | ||
</div> | ||
<div class="d-grid"> | ||
<button type="submit" class="btn btn-success">Register</button> | ||
</div> | ||
</form> | ||
<p class="text-center mt-3"> | ||
Already have an account? <a href="{{ url_for('auth.login') }}">Login here</a> | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
{% endblock %} |
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,4 @@ | ||
Flask==3.0.0 | ||
Flask-SQLAlchemy==3.1.1 | ||
Flask-Login==0.6.3 | ||
werkzeug==3.0.1 |
Oops, something went wrong.