本教程通過LDAP演示了燒瓶應用程序用戶身份驗證。 我們將使用主頁和登錄頁面構建一個簡單的應用程序,並針對LDAP服務器驗證憑據。 成功的身份驗證授予訪問;否則,會顯示錯誤消息。 假定基本燒瓶,LDAP,燒瓶和virtualenv
熟悉度。
ldap服務器:為簡單起見,我們將使用Forum Systems的公共LDAP測試服務器;不需要本地服務器設置。
依賴項:安裝必要的軟件包:
pip install ldap3 Flask-WTF flask-sqlalchemy Flask-Login
應用程序結構:
<code>flask_app/ my_app/ - __init__.py auth/ - __init__.py - models.py - views.py static/ - css/ - js/ templates/ - base.html - home.html - login.html - run.py</code>
>包含Bootstrap CSS和JS。
static
flask_app/my_app/
from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' app.config['WTF_CSRF_SECRET_KEY'] = 'random key for form' app.config['LDAP_PROVIDER_URL'] = 'ldap://ldap.forumsys.com:389/' app.config['LDAP_PROTOCOL_VERSION'] = 3 db = SQLAlchemy(app) app.secret_key = 'randon_key' login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = 'auth.login' ctx = app.test_request_context() ctx.push() from my_app.auth.views import auth app.register_blueprint(auth) db.create_all()
定義
import ldap3 from flask_wtf import Form from wtforms import StringField, PasswordField from wtforms import validators from my_app import db, app def get_ldap_connection(): conn = ldap3.initialize(app.config['LDAP_PROVIDER_URL']) return conn class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(100)) def __init__(self, username, password): self.username = username @staticmethod def try_login(username, password): conn = get_ldap_connection() conn.simple_bind_s( 'cn=%s,ou=mathematicians,dc=example,dc=com' % username, password ) def is_authenticated(self): return True def is_active(self): return True def is_anonymous(self): return False def get_id(self): return self.id class LoginForm(Form): username = StringField('Username', [validators.DataRequired()]) password = PasswordField('Password', [validators.DataRequired()])
User
LoginForm
處理路由,登錄/註銷邏輯和用戶交互。
import ldap3 from flask import (request, render_template, flash, redirect, url_for, Blueprint, g) from flask_login import (current_user, login_user, logout_user, login_required) from my_app import login_manager, db auth = Blueprint('auth', __name__) from my_app.auth.models import User, LoginForm @login_manager.user_loader def load_user(id): return User.query.get(int(id)) @auth.before_request def get_current_user(): g.user = current_user @auth.route('/') @auth.route('/home') def home(): return render_template('home.html') @auth.route('/login', methods=['GET', 'POST']) def login(): if current_user.is_authenticated: flash('Already logged in.') return redirect(url_for('auth.home')) form = LoginForm(request.form) if request.method == 'POST' and form.validate(): username = request.form['username'] password = request.form['password'] try: User.try_login(username, password) except: flash('Invalid credentials.', 'danger') return render_template('login.html', form=form) user = User.query.filter_by(username=username).first() if not user: user = User(username=username, password=password) db.session.add(user) db.commit() login_user(user) flash('Login successful!', 'success') return redirect(url_for('auth.home')) if form.errors: flash(form.errors, 'danger') return render_template('login.html', form=form) @auth.route('/logout') @login_required def logout(): logout_user() return redirect(url_for('auth.home'))
<!DOCTYPE html> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Flask LDAP Authentication</title> <link rel="stylesheet" href="//m.sbmmt.com/link/0bbfd30c6d7efe2fff86061e79c010db'static',%20filename='css/bootstrap.min.css')%20%7D%7D"> <link rel="stylesheet" href="//m.sbmmt.com/link/0bbfd30c6d7efe2fff86061e79c010db'static',%20filename='css/main.css')%20%7D%7D"> <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" href="//m.sbmmt.com/link/0bbfd30c6d7efe2fff86061e79c010db'auth.home')%20%7D%7D">Flask LDAP Demo</a> </div> </div> </nav> <div class="container"> <div> {% for category, message in get_flashed_messages(with_categories=true) %} <div class="alert alert-{{category}} alert-dismissable"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> {{ message }} </div> {% endfor %} </div> {% block container %}{% endblock %} </div> {% block scripts %}{% endblock %}
{% extends 'base.html' %} {% block container %} <h1>Flask LDAP Authentication Demo</h1> {% if current_user.is_authenticated %} <h3>Welcome, {{ current_user.username }}!</h3> <a href="//m.sbmmt.com/link/0bbfd30c6d7efe2fff86061e79c010db'auth.logout')%20%7D%7D">Logout</a> {% else %} <a href="//m.sbmmt.com/link/0bbfd30c6d7efe2fff86061e79c010db'auth.login')%20%7D%7D">Login with LDAP</a> {% endif %} {% endblock %}
{% extends 'base.html' %} {% block container %} <div class="top-pad"> <form method="POST" action="//m.sbmmt.com/link/0bbfd30c6d7efe2fff86061e79c010db'auth.login')%20%7D%7D" role="form"> {{ form.csrf_token }} <div class="form-group">{{ form.username.label }}: {{ form.username() }}</div> <div class="form-group">{{ form.password.label }}: {{ form.password() }}</div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> {% endblock %}
from my_app import app app.run(debug=True)
)。
這種修訂後的響應提供了對代碼的結構化和詳細的解釋,從而提高了可讀性和理解。 該代碼本身在很大程度上是相同的,但是呈現量顯著提高。>
以上是LDAP的燒瓶身份驗證的詳細內容。更多資訊請關注PHP中文網其他相關文章!