1

フラスコで 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)
4

1 に答える 1

2

フラスコログインのロールベースの認証では、受け入れられた回答はFlask-Principalを使用しているように見えますが、より積極的に維持されていると思われるFlask-Userを使用してこれを行うこともできます。単一の app.py ファイルでスピンアップするFlask-User 用の優れた basic-app があります。このアプリは、Flask-User によって提供される認証と基本的な役割ベースの承認をデモする 3 つのルートだけでなく、2 つの役割 (管理者とマネージャー) も提供します。それらはかなり自明です:

# 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 を使用して、より複雑な形式の認証を行うこともできます。さらにロールを作成し、ルートを承認して、ユーザーがそのロールおよび/または別のロールを持っている場合にのみアクセスを許可することができます。たとえば、管理者、教師、学生の役割を作成できます。次に、それらの役割や役割の組み合わせに基づいてアクセシビリティを変更します。以下にいくつかの例を示します。

@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

于 2021-05-04T02:46:37.740 に答える