simran40 commited on
Commit
e627d25
·
verified ·
1 Parent(s): 479644c

Upload 10 files

Browse files
Files changed (9) hide show
  1. Dockerfile +13 -0
  2. LICENSE +21 -0
  3. README.md +382 -4
  4. app.py +152 -0
  5. requirements.txt +4 -0
  6. templates/home.html +11 -0
  7. templates/login.html +23 -0
  8. templates/signup.html +19 -0
  9. users.db +0 -0
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ RUN useradd -m -u 1000 user
4
+ USER user
5
+ ENV PATH="/home/user/.local/bin:$PATH"
6
+
7
+ WORKDIR /app
8
+
9
+ COPY --chown=user ./requirements.txt requirements.txt
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
+
12
+ COPY --chown=user . /app
13
+ CMD ["gunicorn", "app:app", "-b", "0.0.0.0:7860"]
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rahul Bhaskar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md CHANGED
@@ -1,10 +1,388 @@
1
  ---
2
- title: LOGIN
3
- emoji: 🚀
4
  colorFrom: green
5
- colorTo: blue
6
  sdk: docker
7
- pinned: false
 
 
8
  ---
9
 
10
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Flask Login
3
+ emoji: 💻
4
  colorFrom: green
5
+ colorTo: indigo
6
  sdk: docker
7
+ pinned: true
8
+ license: mit
9
+ short_description: A simple yet comprehensive Flask-based user authentication.
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
13
+
14
+ ---
15
+
16
+ # Flask Login System 🔐
17
+
18
+ A simple yet comprehensive Flask-based user authentication system with SQLite database integration, featuring user registration, login, session management, and "Remember Me" functionality.
19
+
20
+ **Live Demo:** [https://rahul23232-flask-login.hf.space/](https://rahul23232-flask-login.hf.space/)
21
+
22
+ ## 📋 Table of Contents
23
+
24
+ - [Features](#features)
25
+ - [Technologies Used](#technologies-used)
26
+ - [Installation](#installation)
27
+ - [Usage](#usage)
28
+ - [Project Structure](#project-structure)
29
+ - [API Routes](#api-routes)
30
+ - [Database Schema](#database-schema)
31
+ - [Security Considerations](#security-considerations)
32
+ - [Contributing](#contributing)
33
+ - [License](#license)
34
+
35
+ ## ✨ Features
36
+
37
+ - **User Registration**: Create new user accounts with unique usernames
38
+ - **User Authentication**: Secure login system with credential verification
39
+ - **Session Management**: Server-side session handling for user state
40
+ - **Remember Me**: Optional persistent login that survives browser restarts
41
+ - **Cookie Management**: Last visit tracking with customizable expiration
42
+ - **SQLite Integration**: Lightweight database for user storage
43
+ - **Responsive Design**: Clean, user-friendly interface
44
+ - **Error Handling**: Proper validation and error messages
45
+
46
+ ## 🛠️ Technologies Used
47
+
48
+ - **Backend**: Python 3.x, Flask
49
+ - **Database**: SQLite3
50
+ - **Frontend**: HTML, CSS (Bootstrap-compatible)
51
+ - **Session Management**: Flask Sessions
52
+ - **Deployment**: Hugging Face Spaces
53
+
54
+ ## 📦 Installation
55
+
56
+ ### Prerequisites
57
+
58
+ - Python 3.7 or higher
59
+ - pip (Python package installer)
60
+
61
+ ### Local Setup
62
+
63
+ 1. **Clone the repository**
64
+ ```bash
65
+ git clone https://github.com/yourusername/flask-login-system.git
66
+ cd flask-login-system
67
+ ```
68
+
69
+ 2. **Install dependencies**
70
+ ```bash
71
+ pip install flask
72
+ ```
73
+
74
+ 3. **Run the application**
75
+ ```bash
76
+ python app.py
77
+ ```
78
+
79
+ 4. **Access the application**
80
+ - Open your browser and navigate to `http://localhost:5000`
81
+
82
+ ### Docker Setup (for Hugging Face Spaces)
83
+
84
+ The project includes Docker configuration for deployment on Hugging Face Spaces:
85
+
86
+ ```dockerfile
87
+ FROM python:3.9-slim
88
+
89
+ WORKDIR /app
90
+
91
+ COPY requirements.txt .
92
+ RUN pip install -r requirements.txt
93
+
94
+ COPY . .
95
+
96
+ EXPOSE 7860
97
+
98
+ CMD ["python", "app.py"]
99
+ ```
100
+
101
+ ## 🎯 Usage
102
+
103
+ ### Getting Started
104
+
105
+ 1. **Access the Application**: Navigate to the home URL
106
+ 2. **Create Account**: Click "Sign Up" to create a new user account
107
+ 3. **Login**: Use your credentials to log in
108
+ 4. **Remember Me**: Check the "Remember Me" option to stay logged in
109
+ 5. **Logout**: Click "Logout" to end your session
110
+
111
+ ### User Flow
112
+
113
+ ```mermaid
114
+ graph TD
115
+ A[Visit Homepage] --> B{User Logged In?}
116
+ B -->|No| C[Redirect to Login]
117
+ B -->|Yes| D[Show Dashboard]
118
+ C --> E[Login Form]
119
+ E --> F[Submit Credentials]
120
+ F --> G{Valid Credentials?}
121
+ G -->|No| H[Show Error]
122
+ G -->|Yes| I[Create Session]
123
+ I --> J{Remember Me?}
124
+ J -->|Yes| K[Set Permanent Session]
125
+ J -->|No| L[Set Temporary Session]
126
+ K --> D
127
+ L --> D
128
+ D --> M[Logout Option]
129
+ M --> N[Clear Session & Cookies]
130
+ N --> C
131
+ ```
132
+
133
+ ## 📁 Project Structure
134
+
135
+ ```
136
+ flask-login-system/
137
+ ├── app.py # Main Flask application
138
+ ├── templates/ # HTML templates
139
+ │ ├── base.html # Base template
140
+ │ ├── login.html # Login page
141
+ │ ├── signup.html # Registration page
142
+ │ └── home.html # Dashboard/home page
143
+ ├── static/ # Static files (CSS, JS, images)
144
+ │ └── style.css # Custom styles
145
+ ├── users.db # SQLite database (created automatically)
146
+ ├── requirements.txt # Python dependencies
147
+ ├── Dockerfile # Docker configuration
148
+ ├── README.md # Project documentation
149
+ └── .gitignore # Git ignore rules
150
+ ```
151
+
152
+ ## 🛣️ API Routes
153
+
154
+ ### Public Routes
155
+
156
+ | Route | Method | Description | Parameters |
157
+ |-------|---------|-------------|------------|
158
+ | `/login` | GET, POST | User login page | `username`, `password`, `remember` |
159
+ | `/signup` | GET, POST | User registration | `username`, `password` |
160
+
161
+ ### Protected Routes
162
+
163
+ | Route | Method | Description | Authentication Required |
164
+ |-------|---------|-------------|------------------------|
165
+ | `/` | GET | Homepage/Dashboard | Yes |
166
+ | `/logout` | GET | User logout | Yes |
167
+
168
+ ### Route Details
169
+
170
+ #### `/` (Homepage)
171
+ - **Method**: GET
172
+ - **Authentication**: Required
173
+ - **Description**: Main dashboard showing welcome message and last visit info
174
+ - **Response**: Redirects to login if not authenticated
175
+
176
+ #### `/signup` (Registration)
177
+ - **Methods**: GET, POST
178
+ - **Parameters**:
179
+ - `username` (string): Unique username
180
+ - `password` (string): User password
181
+ - **Validation**: Username must be unique
182
+ - **Response**: Redirects to login on success
183
+
184
+ #### `/login` (Authentication)
185
+ - **Methods**: GET, POST
186
+ - **Parameters**:
187
+ - `username` (string): User's username
188
+ - `password` (string): User's password
189
+ - `remember` (checkbox): Optional "Remember Me"
190
+ - **Response**: Redirects to homepage on success
191
+
192
+ #### `/logout` (Session Termination)
193
+ - **Method**: GET
194
+ - **Description**: Clears session and cookies
195
+ - **Response**: Redirects to login page
196
+
197
+ ## 🗄️ Database Schema
198
+
199
+ ### Users Table
200
+
201
+ ```sql
202
+ CREATE TABLE users (
203
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
204
+ username TEXT UNIQUE NOT NULL,
205
+ password TEXT NOT NULL
206
+ );
207
+ ```
208
+
209
+ | Column | Type | Constraints | Description |
210
+ |--------|------|-------------|-------------|
211
+ | `id` | INTEGER | PRIMARY KEY, AUTOINCREMENT | Unique user identifier |
212
+ | `username` | TEXT | UNIQUE, NOT NULL | User's login name |
213
+ | `password` | TEXT | NOT NULL | User's password (plain text) |
214
+
215
+ ### Database Operations
216
+
217
+ - **Connection**: SQLite3 with `sqlite3.Row` factory for dictionary-like access
218
+ - **Initialization**: Automatic table creation on first run
219
+ - **Queries**: Parameterized queries to prevent SQL injection
220
+
221
+ ## 🔒 Security Considerations
222
+
223
+ ### Current Implementation
224
+
225
+ - ✅ SQL injection protection via parameterized queries
226
+ - ✅ Session-based authentication
227
+ - ✅ CSRF protection through Flask's secret key
228
+ - ✅ Input validation and error handling
229
+
230
+ ### Production Recommendations
231
+
232
+ - ⚠️ **Password Hashing**: Currently stores plain text passwords
233
+ ```python
234
+ from werkzeug.security import generate_password_hash, check_password_hash
235
+
236
+ # For registration
237
+ hashed_password = generate_password_hash(password)
238
+
239
+ # For login verification
240
+ check_password_hash(stored_hash, provided_password)
241
+ ```
242
+
243
+ - ⚠️ **Environment Variables**: Move secret key to environment variables
244
+ ```python
245
+ import os
246
+ app.secret_key = os.environ.get('SECRET_KEY', 'fallback-secret-key')
247
+ ```
248
+
249
+ - ⚠️ **HTTPS**: Enable HTTPS in production
250
+ - ⚠️ **Rate Limiting**: Implement login attempt limits
251
+ - ⚠️ **Input Validation**: Add comprehensive input sanitization
252
+ - ⚠️ **Session Security**: Configure secure session cookies
253
+
254
+ ### Recommended Security Enhancements
255
+
256
+ ```python
257
+ # Enhanced security configuration
258
+ app.config.update(
259
+ SESSION_COOKIE_SECURE=True, # HTTPS only
260
+ SESSION_COOKIE_HTTPONLY=True, # No JS access
261
+ SESSION_COOKIE_SAMESITE='Lax', # CSRF protection
262
+ PERMANENT_SESSION_LIFETIME=timedelta(hours=1) # Shorter sessions
263
+ )
264
+ ```
265
+
266
+ ## 🎨 Frontend Templates
267
+
268
+ ### Template Structure
269
+
270
+ All templates extend `base.html` for consistent styling:
271
+
272
+ ```html
273
+ <!-- base.html -->
274
+ <!DOCTYPE html>
275
+ <html lang="en">
276
+ <head>
277
+ <meta charset="UTF-8">
278
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
279
+ <title>{% block title %}Flask Login System{% endblock %}</title>
280
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
281
+ </head>
282
+ <body>
283
+ <div class="container mt-4">
284
+ {% block content %}{% endblock %}
285
+ </div>
286
+ </body>
287
+ </html>
288
+ ```
289
+
290
+ ### Form Examples
291
+
292
+ #### Login Form
293
+ ```html
294
+ <form method="POST">
295
+ <div class="mb-3">
296
+ <label for="username" class="form-label">Username</label>
297
+ <input type="text" class="form-control" name="username" required>
298
+ </div>
299
+ <div class="mb-3">
300
+ <label for="password" class="form-label">Password</label>
301
+ <input type="password" class="form-control" name="password" required>
302
+ </div>
303
+ <div class="mb-3 form-check">
304
+ <input type="checkbox" class="form-check-input" name="remember">
305
+ <label class="form-check-label">Remember Me</label>
306
+ </div>
307
+ <button type="submit" class="btn btn-primary">Login</button>
308
+ </form>
309
+ ```
310
+
311
+ ## 🚀 Deployment
312
+
313
+ ### Hugging Face Spaces
314
+
315
+ The project is configured for deployment on Hugging Face Spaces:
316
+
317
+ 1. **Create Space**: Create a new Space on Hugging Face
318
+ 2. **Upload Files**: Push your code to the Space repository
319
+ 3. **Configuration**: Ensure `app.py` runs on port 7860
320
+ 4. **Environment**: The Space will automatically build and deploy
321
+
322
+ ### Local Development
323
+
324
+ ```bash
325
+ # Development mode with auto-reload
326
+ export FLASK_ENV=development
327
+ export FLASK_DEBUG=1
328
+ python app.py
329
+ ```
330
+
331
+ ### Production Deployment
332
+
333
+ ```bash
334
+ # Use a production WSGI server
335
+ pip install gunicorn
336
+ gunicorn -w 4 -b 0.0.0.0:5000 app:app
337
+ ```
338
+
339
+ ## 🤝 Contributing
340
+
341
+ 1. Fork the repository
342
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
343
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
344
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
345
+ 5. Open a Pull Request
346
+
347
+ ### Development Guidelines
348
+
349
+ - Follow PEP 8 style guidelines
350
+ - Add comments for complex logic
351
+ - Update documentation for new features
352
+ - Test all functionality before submitting
353
+
354
+ ## 📝 License
355
+
356
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
357
+
358
+ ## 🐛 Known Issues
359
+
360
+ - Plain text password storage (security concern)
361
+ - No password strength validation
362
+ - No account recovery mechanism
363
+ - Limited input sanitization
364
+
365
+ ## 🔮 Future Enhancements
366
+
367
+ - [ ] Password hashing with bcrypt/scrypt
368
+ - [ ] Email verification system
369
+ - [ ] Password reset functionality
370
+ - [ ] User profile management
371
+ - [ ] Role-based access control
372
+ - [ ] OAuth integration (Google, GitHub)
373
+ - [ ] Rate limiting and brute force protection
374
+ - [ ] Advanced session management
375
+ - [ ] API endpoints for mobile apps
376
+ - [ ] Unit and integration tests
377
+
378
+ ## 📞 Support
379
+
380
+ For questions, issues, or contributions:
381
+
382
+ - **Repository**: [GitHub Repository](https://github.com/yourusername/flask-login-system)
383
+ - **Live Demo**: [Flask Login System](https://rahul23232-flask-login.hf.space/)
384
+ - **Issues**: Use GitHub Issues for bug reports and feature requests
385
+
386
+ ---
387
+
388
+ **Note**: This is a demonstration project for educational purposes. For production use, implement proper security measures including password hashing, HTTPS, and comprehensive input validation.
app.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ """
3
+ Flask Login System with SQLite
4
+ Features:
5
+ - Signup (create new account)
6
+ - Login (check user credentials)
7
+ - Session (to remember login state)
8
+ - Cookies (to store last visit info)
9
+ - "Remember Me" option (stay logged in even after closing browser)
10
+ """
11
+
12
+ from flask import Flask, render_template, request, redirect, url_for, session, make_response
13
+ import sqlite3
14
+ from datetime import timedelta
15
+
16
+ # Flask App Setup
17
+ app = Flask(__name__)
18
+
19
+ # Secret key is used to sign session data (must be kept secret in real apps!)
20
+ app.secret_key = "supersecretkey"
21
+
22
+ # Permanent sessions last for 7 days (used when "Remember Me" is checked)
23
+ app.permanent_session_lifetime = timedelta(days=7)
24
+
25
+
26
+ # Helper function to connect to SQLite database
27
+ def get_db_connection():
28
+ # Connect to SQLite database (creates file users.db if it doesn’t exist)
29
+ conn = sqlite3.connect("users.db")
30
+ conn.row_factory = sqlite3.Row # Makes rows behave like dictionaries
31
+ return conn
32
+
33
+
34
+ # Initialize database with a "users" table
35
+ def init_db():
36
+ conn = get_db_connection()
37
+ conn.execute("""
38
+ CREATE TABLE IF NOT EXISTS users (
39
+ id INTEGER PRIMARY KEY AUTOINCREMENT, -- Auto-increment ID
40
+ username TEXT UNIQUE NOT NULL, -- Unique username
41
+ password TEXT NOT NULL -- Password (plain text for demo, should use hashing!)
42
+ )
43
+ """)
44
+ conn.commit()
45
+ conn.close()
46
+
47
+ # Call database initialization at startup
48
+ init_db()
49
+
50
+
51
+ # Home Page (only logged-in users can see this)
52
+ @app.route("/")
53
+ def home():
54
+ # Check if the user is logged in using session
55
+ if "username" in session:
56
+ username = session["username"] # Get logged-in username from session
57
+
58
+ # Get last visit message from cookie (if not found, show default message)
59
+ last_visit = request.cookies.get("last_visit", "First time visiting!")
60
+
61
+ return render_template("home.html", username=username, last_visit=last_visit)
62
+
63
+ # If not logged in, redirect to login page
64
+ return redirect(url_for("login"))
65
+
66
+
67
+ # Signup Page
68
+ @app.route("/signup", methods=["GET", "POST"])
69
+ def signup():
70
+ if request.method == "POST": # When user submits the form
71
+ username = request.form["username"]
72
+ password = request.form["password"]
73
+
74
+ conn = get_db_connection()
75
+ try:
76
+ # Insert new user into database
77
+ conn.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, password))
78
+ conn.commit()
79
+ conn.close()
80
+
81
+ # After signup, redirect to login page
82
+ return redirect(url_for("login"))
83
+
84
+ except sqlite3.IntegrityError:
85
+ # This happens if the username already exists
86
+ return "Username already exists! Try another."
87
+
88
+ # If GET request, show signup form
89
+ return render_template("signup.html")
90
+
91
+
92
+ # Login Page
93
+ @app.route("/login", methods=["GET", "POST"])
94
+ def login():
95
+ if request.method == "POST": # When user submits login form
96
+ username = request.form["username"]
97
+ password = request.form["password"]
98
+
99
+ # Checkbox value: will be "on" if user ticks "Remember Me"
100
+ remember = request.form.get("remember")
101
+
102
+ # Check if username & password exist in database
103
+ conn = get_db_connection()
104
+ user = conn.execute("SELECT * FROM users WHERE username=? AND password=?",
105
+ (username, password)).fetchone()
106
+ conn.close()
107
+
108
+ if user:
109
+ # ✅ User found → start session
110
+ if remember == "on":
111
+ # Session will survive browser close (7 days)
112
+ session.permanent = True
113
+ else:
114
+ # Session ends when browser closes
115
+ session.permanent = False
116
+
117
+ # Store username inside session
118
+ session["username"] = username
119
+
120
+ # Create response with cookie
121
+ resp = make_response(redirect(url_for("home")))
122
+
123
+ # Save a cookie with "last visit" info
124
+ # If "Remember Me" checked → cookie valid for 7 days
125
+ # Else → cookie lasts only until browser closes
126
+ resp.set_cookie("last_visit", "Welcome back, " + username,
127
+ max_age=(7*24*60*60 if remember == "on" else None))
128
+
129
+ return resp
130
+ else:
131
+ # If username or password is wrong
132
+ return "Invalid username or password. Try again."
133
+
134
+ # If GET request, show login form
135
+ return render_template("login.html")
136
+
137
+
138
+ # Logout Page
139
+ @app.route("/logout")
140
+ def logout():
141
+ # Remove username from session
142
+ session.pop("username", None)
143
+
144
+ # Also delete the "last_visit" cookie
145
+ resp = make_response(redirect(url_for("login")))
146
+ resp.set_cookie("last_visit", "", expires=0)
147
+ return resp
148
+
149
+
150
+ # Run the App
151
+ if __name__ == "__main__":
152
+ app.run(debug=True, host="0.0.0.0", port=5000)
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ flask
2
+ gunicorn
3
+ requests
4
+ datetime
templates/home.html ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Home</title>
5
+ </head>
6
+ <body>
7
+ <h2>Welcome, {{ username }}!</h2>
8
+ <p>Last visit info (from cookie): {{ last_visit }}</p>
9
+ <a href="{{ url_for('logout') }}">Logout</a>
10
+ </body>
11
+ </html>
templates/login.html ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Login</title>
5
+ </head>
6
+ <body>
7
+ <h2>Login</h2>
8
+ <form method="POST">
9
+ <label>Username:</label>
10
+ <input type="text" name="username" required><br><br>
11
+
12
+ <label>Password:</label>
13
+ <input type="password" name="password" required><br><br>
14
+
15
+ <label>
16
+ <input type="checkbox" name="remember"> Remember Me
17
+ </label><br><br>
18
+
19
+ <button type="submit">Login</button>
20
+ </form>
21
+ <p>Don't have an account? <a href="{{ url_for('signup') }}">Signup here</a></p>
22
+ </body>
23
+ </html>
templates/signup.html ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Signup</title>
5
+ </head>
6
+ <body>
7
+ <h2>Signup</h2>
8
+ <form method="POST">
9
+ <label>Username:</label>
10
+ <input type="text" name="username" required><br><br>
11
+
12
+ <label>Password:</label>
13
+ <input type="password" name="password" required><br><br>
14
+
15
+ <button type="submit">Signup</button>
16
+ </form>
17
+ <p>Already have an account? <a href="{{ url_for('login') }}">Login here</a></p>
18
+ </body>
19
+ </html>
users.db ADDED
Binary file (16.4 kB). View file