如何在Python+MongoDB(Django+PyMongo)中实现登录与个人页的会话管理验证?
Hey there! Let's walk through how to handle session creation, management, and validation for your Django + PyMongo setup—since you're skipping Django's ORM and built-in auth, we'll tailor this to your workflow:
Django comes with session handling out of the box, but double-check your settings.py to make sure these middlewares are present in the MIDDLEWARE list (they should be there by default, but it's good to verify):
MIDDLEWARE = [ # ... other middlewares 'django.contrib.sessions.middleware.SessionMiddleware', # You can skip AuthenticationMiddleware since you're not using Django's auth system ]
This middleware takes care of creating session cookies, persisting session data, and attaching the request.session object to every request.
In your /login view, validate the user's credentials against your MongoDB collection first. If they're valid, store a unique user identifier (like the MongoDB _id or username) in the session to track the user.
Here's a sample implementation:
from django.shortcuts import render, redirect from pymongo import MongoClient from django.contrib.auth.hashers import make_password, check_password # For secure password handling def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # Reuse your MongoDB connection (better to move this to a separate utility file later!) client = MongoClient('mongodb://localhost:27017/') db = client['your_app_db'] users_col = db['users'] # Fetch user by username, then verify password (NEVER store plaintext passwords!) user = users_col.find_one({'username': username}) if user and check_password(password, user['password']): # Store user ID as string (MongoDB ObjectId can't be serialized directly) request.session['user_id'] = str(user['_id']) request.session['username'] = user['username'] # Optional: store frequent-use fields return redirect('profile') # Redirect to profile after login else: return render(request, 'login.html', {'error': 'Invalid username or password'}) return render(request, 'login.html')
⚠️ Critical note: Always hash passwords before storing them in MongoDB. Use make_password() when creating user accounts, and check_password() to verify them—this avoids exposing plaintext passwords if your database is ever compromised.
Before rendering the profile, check if the session contains a valid user_id. If not, redirect back to login. You should also verify the user still exists in MongoDB to handle cases where the user was deleted after logging in.
from django.shortcuts import render, redirect from pymongo import MongoClient from bson.objectid import ObjectId def profile(request): # Check if user is logged in via session if 'user_id' not in request.session: return redirect('login') # Fetch user from MongoDB using the session's user ID client = MongoClient('mongodb://localhost:27017/') db = client['your_app_db'] users_col = db['users'] user = users_col.find_one({'_id': ObjectId(request.session['user_id'])}) if not user: # User no longer exists—clear the invalid session del request.session['user_id'] return redirect('login') # Pass user data to the profile template return render(request, 'profile.html', {'user': user})
Add a logout view to clear the user's session data, so they can't access the profile without logging in again:
from django.shortcuts import redirect def logout(request): # Remove user-specific session data if 'user_id' in request.session: del request.session['user_id'] # Or use request.session.flush() to clear the entire session (including CSRF tokens) return redirect('login')
- Reuse MongoDB connections: Don't create a new
MongoClientin every view. Instead, initialize it once (e.g., in autils.pyfile or Django app config) to avoid connection overhead. - Secure your sessions: Update
settings.pyto harden session cookies:SESSION_COOKIE_HTTPONLY = True # Prevents XSS from accessing session cookies SESSION_COOKIE_SECURE = True # Only send cookies over HTTPS (use in production) SESSION_EXPIRE_AT_BROWSER_CLOSE = True # Optional: Session expires when browser closes SESSION_COOKIE_AGE = 3600 # Optional: Auto-logout after 1 hour (in seconds) - Use a custom login decorator: Avoid repeating session-check logic in every protected view. Create a decorator to reuse:
Then decorate your profile view:from django.shortcuts import redirect from bson.objectid import ObjectId from pymongo import MongoClient def login_required(view_func): def wrapper(request, *args, **kwargs): if 'user_id' not in request.session: return redirect('login') # Optional: Validate user still exists in DB client = MongoClient('mongodb://localhost:27017/') user = client['your_app_db']['users'].find_one({'_id': ObjectId(request.session['user_id'])}) if not user: del request.session['user_id'] return redirect('login') return view_func(request, *args, **kwargs) return wrapper@login_required def profile(request): # Your profile logic here
内容的提问来源于stack exchange,提问作者Praneeth Karnena

