我如何使用 flask login_required 装饰器控制多个登录(如管理员登录和普通登录)
How can i control multiple logins(like admin login and normal login) with flask login_required decorator
我想在 Flask 中使用 login_required 装饰器控制多个登录。在我的项目中,我只希望管理员能够添加文章,而注册用户能够评论它们。我对未注册用户隐藏了注销页面和个人资料页面,但我无法对注册用户隐藏添加文章页面我该如何解决这个问题?
from flask import Flask,render_template,flash,redirect,url_for,session,logging,request
from flask_mysqldb import MySQL
from wtforms import Form,StringField,TextAreaField,PasswordField,validators
import email_validator
from passlib.hash import pbkdf2_sha256
from functools import wraps
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if "logged_in" in session:
return f(*args, **kwargs)
else:
flash("Bu Sayfayı Görüntülemek İçin Giriş Yapmalısınız","danger")
return redirect(location=(url_for("login")))
return decorated_function
@app.before_request
def before_request_func():
class RegisterForm(Form):
name = StringField("İsim Soyisim", validators=[validators.Length(min=4,message="En az 4 karakter uzunluğunda bir girdi giriniz"),validators.DataRequired()])
user_name = StringField("Kullanıcı Adı", validators=[validators.Length(min=4,message="En az 4 karakter uzunluğunda bir girdi giriniz"),validators.DataRequired()])
email = StringField("Email Adresi", validators=[validators.Length(min=4,message="En az 4 karakter uzunluğunda bir girdi giriniz"),validators.DataRequired(),validators.Email(message="Lütfen Geçerli Bir Email Giriniz")])
password = PasswordField("Şifre",validators=[validators.DataRequired("Lütfen Bir Parola Belirleyin"),validators.EqualTo(fieldname="confirm",message="Parolanız Uyuşmuyor")])
confirm = PasswordField("Parola Doğrula")
class LoginForm(Form):
email = StringField("Email Adresi",validators=[validators.DataRequired(message="Lütfen Emailinizi Giriniz")])
password = PasswordField("Şifre",validators=[validators.DataRequired(message="Lütfen Şifrenizi Giriniz")])
app = Flask(__name__)
mysql = MySQL(app)
app.secret_key = "furkanselek"
app.config["MYSQL_DATABASE_HOST"] = "localhost"
app.config["MYSQL_DATABASE_USER"] = "root"
app.config["MYSQL_DATABASE_PASSWORD"] = ""
app.config["MYSQL_DB"] = "furkanselek"
app.config['MYSQL_CURSORCLASS'] = "DictCursor"
app.config["MYSQL_DATABASE_PORT"] = "3306"
@app.route("/")
def index():
return render_template("index.html")
@app.route("/about")
def about():
return render_template("about.html")
@app.route("/register",methods=["GET","POST"])
def register():
form = RegisterForm(request.form)
if request.method == "POST" and form.validate():
name = form.name.data
username = form.user_name.data
email = form.email.data
password = pbkdf2_sha256.encrypt(form.password.data)
cursor = mysql.connection.cursor()
sorgu = ("Insert into users (name,email,username,password) VALUES(%s,%s,%s,%s)")
cursor.execute(sorgu,(name,email,username,password))
mysql.connection.commit()
cursor.close()
flash("Başarıyla Kayıt Oldunuz",category="warning")
return redirect(location =(url_for("login")))
else:
return render_template("register.html",form= form)
@app.route("/login",methods=["GET","POST"])
def login():
form = LoginForm(request.form)
if request.method == "POST" and form.validate():
email = form.email.data
password_entered = form.password.data
cursor = mysql.connection.cursor()
query = ("SELECT * FROM users WHERE email = %s")
result = cursor.execute(query,(email,))
if result > 0:
data = cursor.fetchone()
username = data["username"]
password = data["password"]
if pbkdf2_sha256.verify(password_entered,password):
flash("Başarıyla Giriş Yaptınız",category="warning")
if username == "maxkonrad":
session["admin"] = True
session["logged_in"] = True
session["username"] = username
return redirect(location=(url_for("index")))
else:
session["logged_in"] = True
session["username"] = username
return redirect(location=(url_for("index")))
else:
flash("Parolanızı Yanlış Girdiniz",category="warning")
return redirect(location=(url_for("login")))
else:
flash("Bu Email ile Kayıt Olmuş Bir Kullanıcı Yok")
return redirect(location=(url_for("login")))
else:
return render_template("login.html",form= form)
@app.route("/logout")
@login_required
def logout():
session.clear()
return redirect(location=(url_for("index")))
@app.route("/addarticle",methods=["GET","POST"])
def addarticle():
return render_template("addarticle.html")
@app.route("/profile")
@login_required
def profile():
return render_template("profile.html")
if __name__ == "__main__":
app.run(debug=True)
在 the accepted answer appears to be using Flask-Principal However, you can also do this with Flask-User which seems to be more actively maintained. There's a superb basic-app for Flask-User 中,其中包含一个 app.py 文件。该应用程序提供两个角色(管理员和经理)以及三个路由,用于演示 Flask-User 提供的身份验证和基于基本角色的授权。它们是不言自明的:
# The Home page is accessible to anyone
@app.route('/')
def home_page():
# The Members page is only accessible to authenticated users
@app.route('/members')
@login_required # Use of @login_required decorator
def member_page():
# The Admin page requires an 'Admin' role.
@app.route('/admin')
@roles_required('Admin') # Use of @roles_required decorator
def admin_page():
Flask-User 也可用于执行更复杂的授权形式。您可以创建更多角色,然后授权路由仅允许具有该角色 and/or 另一个角色的用户访问。例如,您可以创建管理员、教师和学生角色。然后根据这些角色 and/or 角色组合改变可访问性。这里有几个例子:
@admin_blueprint.route('/admin/teacher_or_admin')
@roles_required(['admin', 'teacher']) # requires admin OR teacher role
def admin_teacher_or_admin():
return "You have the right roles to access this page - it requires admin OR teacher roles"
@admin_blueprint.route('/admin/teacher_and_admin')
@roles_required('admin','teacher') # requires admin AND teacher roles
def admin_teacher_and_admin():
return "You have the right roles to access this view"
@admin_blueprint.route('/admin/student')
@roles_required('student')
def admin_student():
return "You have the right roles to access this page - requires student role"
虽然它不像上面的基本用户应用程序那样是单个文件,但此存储库演示了这些更高级的烧瓶用户授权功能:https://github.com/lfernandez55/3200_Final_Project_Challenge
我想在 Flask 中使用 login_required 装饰器控制多个登录。在我的项目中,我只希望管理员能够添加文章,而注册用户能够评论它们。我对未注册用户隐藏了注销页面和个人资料页面,但我无法对注册用户隐藏添加文章页面我该如何解决这个问题?
from flask import Flask,render_template,flash,redirect,url_for,session,logging,request
from flask_mysqldb import MySQL
from wtforms import Form,StringField,TextAreaField,PasswordField,validators
import email_validator
from passlib.hash import pbkdf2_sha256
from functools import wraps
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if "logged_in" in session:
return f(*args, **kwargs)
else:
flash("Bu Sayfayı Görüntülemek İçin Giriş Yapmalısınız","danger")
return redirect(location=(url_for("login")))
return decorated_function
@app.before_request
def before_request_func():
class RegisterForm(Form):
name = StringField("İsim Soyisim", validators=[validators.Length(min=4,message="En az 4 karakter uzunluğunda bir girdi giriniz"),validators.DataRequired()])
user_name = StringField("Kullanıcı Adı", validators=[validators.Length(min=4,message="En az 4 karakter uzunluğunda bir girdi giriniz"),validators.DataRequired()])
email = StringField("Email Adresi", validators=[validators.Length(min=4,message="En az 4 karakter uzunluğunda bir girdi giriniz"),validators.DataRequired(),validators.Email(message="Lütfen Geçerli Bir Email Giriniz")])
password = PasswordField("Şifre",validators=[validators.DataRequired("Lütfen Bir Parola Belirleyin"),validators.EqualTo(fieldname="confirm",message="Parolanız Uyuşmuyor")])
confirm = PasswordField("Parola Doğrula")
class LoginForm(Form):
email = StringField("Email Adresi",validators=[validators.DataRequired(message="Lütfen Emailinizi Giriniz")])
password = PasswordField("Şifre",validators=[validators.DataRequired(message="Lütfen Şifrenizi Giriniz")])
app = Flask(__name__)
mysql = MySQL(app)
app.secret_key = "furkanselek"
app.config["MYSQL_DATABASE_HOST"] = "localhost"
app.config["MYSQL_DATABASE_USER"] = "root"
app.config["MYSQL_DATABASE_PASSWORD"] = ""
app.config["MYSQL_DB"] = "furkanselek"
app.config['MYSQL_CURSORCLASS'] = "DictCursor"
app.config["MYSQL_DATABASE_PORT"] = "3306"
@app.route("/")
def index():
return render_template("index.html")
@app.route("/about")
def about():
return render_template("about.html")
@app.route("/register",methods=["GET","POST"])
def register():
form = RegisterForm(request.form)
if request.method == "POST" and form.validate():
name = form.name.data
username = form.user_name.data
email = form.email.data
password = pbkdf2_sha256.encrypt(form.password.data)
cursor = mysql.connection.cursor()
sorgu = ("Insert into users (name,email,username,password) VALUES(%s,%s,%s,%s)")
cursor.execute(sorgu,(name,email,username,password))
mysql.connection.commit()
cursor.close()
flash("Başarıyla Kayıt Oldunuz",category="warning")
return redirect(location =(url_for("login")))
else:
return render_template("register.html",form= form)
@app.route("/login",methods=["GET","POST"])
def login():
form = LoginForm(request.form)
if request.method == "POST" and form.validate():
email = form.email.data
password_entered = form.password.data
cursor = mysql.connection.cursor()
query = ("SELECT * FROM users WHERE email = %s")
result = cursor.execute(query,(email,))
if result > 0:
data = cursor.fetchone()
username = data["username"]
password = data["password"]
if pbkdf2_sha256.verify(password_entered,password):
flash("Başarıyla Giriş Yaptınız",category="warning")
if username == "maxkonrad":
session["admin"] = True
session["logged_in"] = True
session["username"] = username
return redirect(location=(url_for("index")))
else:
session["logged_in"] = True
session["username"] = username
return redirect(location=(url_for("index")))
else:
flash("Parolanızı Yanlış Girdiniz",category="warning")
return redirect(location=(url_for("login")))
else:
flash("Bu Email ile Kayıt Olmuş Bir Kullanıcı Yok")
return redirect(location=(url_for("login")))
else:
return render_template("login.html",form= form)
@app.route("/logout")
@login_required
def logout():
session.clear()
return redirect(location=(url_for("index")))
@app.route("/addarticle",methods=["GET","POST"])
def addarticle():
return render_template("addarticle.html")
@app.route("/profile")
@login_required
def profile():
return render_template("profile.html")
if __name__ == "__main__":
app.run(debug=True)
在
# The Home page is accessible to anyone
@app.route('/')
def home_page():
# The Members page is only accessible to authenticated users
@app.route('/members')
@login_required # Use of @login_required decorator
def member_page():
# The Admin page requires an 'Admin' role.
@app.route('/admin')
@roles_required('Admin') # Use of @roles_required decorator
def admin_page():
Flask-User 也可用于执行更复杂的授权形式。您可以创建更多角色,然后授权路由仅允许具有该角色 and/or 另一个角色的用户访问。例如,您可以创建管理员、教师和学生角色。然后根据这些角色 and/or 角色组合改变可访问性。这里有几个例子:
@admin_blueprint.route('/admin/teacher_or_admin')
@roles_required(['admin', 'teacher']) # requires admin OR teacher role
def admin_teacher_or_admin():
return "You have the right roles to access this page - it requires admin OR teacher roles"
@admin_blueprint.route('/admin/teacher_and_admin')
@roles_required('admin','teacher') # requires admin AND teacher roles
def admin_teacher_and_admin():
return "You have the right roles to access this view"
@admin_blueprint.route('/admin/student')
@roles_required('student')
def admin_student():
return "You have the right roles to access this page - requires student role"
虽然它不像上面的基本用户应用程序那样是单个文件,但此存储库演示了这些更高级的烧瓶用户授权功能:https://github.com/lfernandez55/3200_Final_Project_Challenge