from flask import Flask, redirect, url_for from flask_login import LoginManager, login_required app = Flask(__name__) login_manager = LoginManager(app) @login_manager.unauthorized_handler def unauthorized(): return redirect(url_for('login')) @app.route('/dashboard') @login_required def dashboard(): return 'Welcome to your dashboard!' @app.route('/login') def login(): return 'Please log in.'
The login_required decorator checks if the user is logged in. If not, it calls the unauthorized_handler which redirects the user to the login page. So the user sees the login page content.
from flask import Flask, session from flask_login import LoginManager, login_user, UserMixin app = Flask(__name__) app.secret_key = 'secret' login_manager = LoginManager(app) class User(UserMixin): def __init__(self, id): self.id = id user = User('123') with app.test_request_context(): login_user(user) user_id_in_session = session.get('_user_id')
Flask-Login stores the logged-in user's ID in the session under the key _user_id. This is how it remembers who is logged in across requests.
from flask import Flask, request from flask_login import LoginManager, login_user, UserMixin app = Flask(__name__) app.secret_key = 'secret' login_manager = LoginManager(app) class User(UserMixin): def __init__(self, id): self.id = id @app.route('/login', methods=['POST']) def login(): username = request.form['username'] if username == 'testuser': user = User('1') login_user(user) return 'Logged in' return 'Failed', 401 client = app.test_client()
The Flask test client sends form data with the data argument as a dictionary. Using json sends JSON, which the route does not expect. GET requests do not send form data in the body.
response = client.post('/login', data={'username': 'testuser'}) response = client.get('/dashboard') assert b'Welcome' in response.data
When accessing a protected route without being logged in, Flask-Login redirects to the login page. The test client must follow redirects to get the final page content. Without follow_redirects=True, the response is the redirect itself, not the dashboard content.
After logout, the user is no longer authenticated. Accessing a protected route redirects to login. Using follow_redirects=True lets the test client get the login page content to verify the user is logged out.