🔐 Lesson: Add User Authentication (Username & Password)
🎯 Goal
Allow users to:
-
🔑 Sign up and log in securely
-
🙍 Personalize chat history & memory
-
🗂️ Store uploads and messages per user
✅ Options for Auth in Streamlit
| Method | Tools | Notes |
|---|---|---|
| 🟩 Built-in Streamlit Login | st.session_state + manual form |
Easy, secure for basic needs |
| 🟦 Firebase Auth | Firebase + Pyrebase | External service, email/password + social login |
| 🟥 Streamlit Auth Component | streamlit-authenticator |
Clean UI, YAML config, hashed passwords |
We’ll start with the easiest and safest:
✅ Option 1: Manual Auth with Hashed Passwords (Secure & Simple)
🧩 Step 1: Install bcrypt for Secure Password Hashing
pip install bcrypt
📁 Step 2: Create users.json
{
"ronny": {
"password": "$2b$12$XhR/1xY13FzmXaYgBJoRauKMRpHf2sfIE9fhE0DRp/V4QxRgWPRPq"
}
}
The value is a hashed password (
"1234"hashed withbcrypt)
You can hash your own with this snippet:
import bcrypt
password = b"1234"
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
print(hashed)
📜 Step 3: Add Login UI to Your app.py
import json
import bcrypt
def load_users():
with open("users.json", "r") as f:
return json.load(f)
def authenticate(username, password):
users = load_users()
if username in users:
stored = users[username]["password"].encode()
return bcrypt.checkpw(password.encode(), stored)
return False
# Login form
if "user" not in st.session_state:
st.subheader("🔐 Login to Your AI Agent")
with st.form("login"):
username = st.text_input("Username")
password = st.text_input("Password", type="password")
submit = st.form_submit_button("Login")
if submit:
if authenticate(username, password):
st.session_state.user = username
st.success(f"Welcome, {username}!")
st.experimental_rerun()
else:
st.error("❌ Invalid username or password")
st.stop()
Now all authenticated users will enter the app normally.
🧠 Step 4: Personalize Per-User Memory & Files
Update your paths like this:
user_folder = os.path.join("user_data", st.session_state.user)
os.makedirs(user_folder, exist_ok=True)
# Save files per user
uploaded_path = os.path.join(user_folder, file.name)
Use user_folder to:
-
Save uploaded documents
-
Store vector DB (
user_data/ronny/db_memory) -
Store chat logs
🗂️ Optional: Show User’s Past Chats
chat_file = os.path.join(user_folder, "chat_log.txt")
def log_chat(user_input, ai_output):
with open(chat_file, "a") as f:
f.write(f"You: {user_input}nBot: {ai_output}nn")
Show in sidebar:
if os.path.exists(chat_file):
with open(chat_file, "r") as f:
st.sidebar.markdown("### 💬 Previous Chats")
st.sidebar.text(f.read())
✅ Summary
✅ Secure login using username + hashed password
✅ Session stored with st.session_state.user
✅ All files, memory, and chat logs are stored per user
26
