如何在项目中设置30秒HTTP Session超时及浏览器跳转拦截
Alright, let's work through your two requirements one by one. I'll provide concrete code examples for views.py, notes on models.py, and tweaks for home.html to get everything working as expected.
First, we need to configure Django's session handling to enforce a 30-second timeout when the user is idle. Here's what to do:
Step 1: Configure Session Settings (in settings.py)
Even though you didn't mention it, we need to set a base session timeout and enable session expiration based on activity. Add these lines to your settings.py:
SESSION_COOKIE_AGE = 30 # Session expires after 30 seconds of inactivity SESSION_SAVE_EVERY_REQUEST = True # Refresh session expiry on every user request SESSION_EXPIRE_AT_BROWSER_CLOSE = True # Optional: Ends session when browser closes
Step 2: Update views.py to Check Session Validity
We'll create a middleware to track user activity and check for session expiry, plus add cache-control headers that tie into your second requirement. We'll also build out the core login/logout/home views:
from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required from datetime import datetime def login_view(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) # Explicitly set session expiry to match our 30-second rule request.session.set_expiry(30) # Track initial activity time request.session['last_activity'] = datetime.now().isoformat() return redirect('home') else: return render(request, 'login.html', {'error': 'Invalid credentials'}) return render(request, 'login.html') def logout_view(request): logout(request) return redirect('login') def session_timeout_middleware(get_response): def middleware(request): if request.user.is_authenticated: # Check if session has expired due to inactivity if 'last_activity' in request.session: last_activity = datetime.fromisoformat(request.session['last_activity']) elapsed_time = (datetime.now() - last_activity).total_seconds() if elapsed_time > 30: logout(request) return redirect('login') # Update activity timestamp on every valid request request.session['last_activity'] = datetime.now().isoformat() response = get_response(request) # Add cache-control headers to prevent browser caching response['Cache-Control'] = 'no-cache, no-store, must-revalidate' response['Pragma'] = 'no-cache' response['Expires'] = '0' return response return middleware @login_required def home(request): # Add your home page business logic here return render(request, 'home.html', {'user': request.user})
Don't forget to add 'yourapp.middlewares.session_timeout_middleware' to your MIDDLEWARE list in settings.py (replace yourapp with your actual app name).
Step 3: Optional User Feedback in home.html
To warn users before they're logged out, add a simple timer script to your template:
<script> let timeoutTimer; function resetSessionTimer() { clearTimeout(timeoutTimer); // Warn 5 seconds before expiry, then redirect to logout timeoutTimer = setTimeout(() => { alert("Your session is about to expire. You'll be logged out in 5 seconds."); setTimeout(() => window.location.href = "{% url 'logout' %}", 5000); }, 25000); } // Reset timer on any user interaction document.addEventListener('mousemove', resetSessionTimer); document.addEventListener('keypress', resetSessionTimer); document.addEventListener('click', resetSessionTimer); // Initialize timer when the page loads resetSessionTimer(); </script>
The core fix here is preventing the browser from caching authenticated pages, so when the user hits back/forward, the browser has to re-request the page from the server (where our session check will redirect to login if the session is invalid).
Step 1: Leverage the Cache-Control Headers
The middleware we added already sets strict cache headers, which tells the browser not to store a local copy of authenticated pages. This means when the user navigates back, the browser will fetch the page fresh from the server, and our session timeout check will kick in if needed.
Step 2: Reinforce Session Checks in Views
The @login_required decorator automatically redirects unauthenticated users to the login page. Combined with our middleware's activity tracking, this ensures that even if a user tries to navigate back to a cached page, the server will validate their session first.
Step 3: home.html Final Tweaks
Make sure your template includes a logout button and doesn't have any static content that might bypass server-side checks:
<!DOCTYPE html> <html> <head> <title>Home Page</title> </head> <body> <h1>Welcome back, {{ user.username }}!</h1> <p>You'll be logged out automatically after 30 seconds of inactivity.</p> <a href="{% url 'logout' %}">Logout Manually</a> <!-- Add the session timeout warning script here --> <script> // ... (timeout script from earlier) </script> </body> </html>
Notes on models.py
For these specific requirements, you don't need to modify models.py unless you're using a custom user model. If you are, just ensure it inherits from Django's AbstractUser or AbstractBaseUser (to stay compatible with Django's authentication system), and the login/logout logic will work as expected.
内容的提问来源于stack exchange,提问作者user9338077

