@requires_auth
.
Декораторы – мощный инструмент Python, который позволяет добавлять функциональность к существующим функциям, не изменяя их код напрямую. В веб-приложении, декораторы могут быть элегантно использованы для реализации авторизации, то есть для проверки, имеет ли пользователь право доступа к определенной функции (например, к обработчику маршрута).
Основная идея: Декоратор оборачивает функцию-обработчик (view function) и выполняет проверку авторизации перед тем, как вызвать саму функцию-обработчик. Если пользователь авторизован, функция-обработчик вызывается. Если нет – выполняется перенаправление на страницу входа или возвращается ошибка (например, 403 Forbidden).
Пример реализации (Flask):
from functools import wraps
from flask import Flask, request, redirect, url_for, abort, session
app = Flask(__name__)
app.secret_key = 'secret' # Очень важно для сессий! Замените на более безопасный ключ.
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if 'username' not in session:
return redirect(url_for('login', next=request.url))
return f(*args, **kwargs)
return decorated_function
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
# Здесь должна быть проверка подлинности пользователя
# (например, сверка с базой данных). Это упрощенный пример.
if username == 'admin' and password == 'password':
session['username'] = username
next_url = request.args.get('next') or url_for('protected')
return redirect(next_url)
else:
return 'Неверные учетные данные'
return '''
<form method="post">
<p>Username: <input type=text name=username>
<p>Password: <input type=password name=password>
<p><input type=submit value=Login>
</form>
'''
@app.route('/logout')
def logout():
session.pop('username', None)
return redirect(url_for('login'))
@app.route('/protected')
@login_required
def protected():
return 'Вы авторизованы! (Username: %s)' % session['username']
@app.route('/')
def index():
return "Hello World! <a href='/login'>Login</a>"
if __name__ == '__main__':
app.run(debug=True)
Разбор примера:
login_required
: Это декоратор. Он принимает функцию f
(обычно view function) в качестве аргумента.@wraps(f)
: Этот декоратор из модуля functools
сохраняет метаданные (имя, docstring и т.д.) оборачиваемой функции f
. Это важно для отладки и интроспекции.decorated_function
: Это внутренняя функция, которая выполняется при вызове декорированной функции.decorated_function
происходит проверка: если в session
нет ключа 'username'
, значит пользователь не авторизован. В этом случае происходит перенаправление на страницу login
.f
(view function) с теми же аргументами.@login_required
: Применение декоратора к функции protected
. Теперь, при обращении к /protected
, сначала выполнится код в login_required
.session
: Используется для хранения информации о состоянии пользователя между запросами (в данном случае, имя пользователя). Важно отметить, что app.secret_key
должен быть установлен для использования сессий.Преимущества использования декораторов для авторизации:
login_required
можно применить к любой view function, требующей авторизации.Альтернативные подходы:
Важно: При реализации авторизации необходимо учитывать безопасность. Никогда не храните пароли в открытом виде. Используйте надежное хеширование и соление. Также, необходимо защищаться от распространенных веб-угроз, таких как XSS и CSRF.