簡體   English   中英

Flask 無數據庫登錄

[英]Flask login without database

我需要為我正在使用的一個應用程序實現一個簡單的登錄功能flask-login 身份驗證檢查是硬編碼的 if 條件,它正在驗證用戶名密碼是否等於給定的字符串。 代碼如下:

@auth_bp.route('/login', methods=["POST"])
def loginHandler():
    username = request.form.get('username')
    password = request.form.get('password')

    if username != 'admin' and password != 'Admin@123':
        flash('Please check your login details and try again.')
        return redirect(url_for('auth_bp.show_login'))

    login_user(username, False)
    # if the above check passes, then we know the user has the right credentials
    return redirect(url_for('migration_bp.list'))

app.py文件中,我有以下代碼:

from flask import Flask
from flask_login import LoginManager, login_manager
from auth.auth import auth_bp
from environments.environments import environments_bp
from migration.migration import migration_bp
from logs.logs import logs_bp

UPLOAD_FOLDER = 'static/uploads'

@login_manager.user_loader
def user_loader():
    # since the user_id is just the primary key of our user table, use it in the query for the user
    return 1

def create_app():

    app = Flask(__name__)

    login_manager_copy = LoginManager()
    login_manager_copy.login_view = 'auth.login'
    login_manager_copy.init_app(app)

    app.register_blueprint(auth_bp, url_prefix='/auth')
    app.register_blueprint(environments_bp, url_prefix='/environments')
    app.register_blueprint(migration_bp, url_prefix='/migration')
    app.register_blueprint(logs_bp, url_prefix='/logs')

    app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
    app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

    return app


if __name__ == '__main__':
    create_app().run(debug=True)

但這顯示錯誤如下:

AttributeError: module 'flask_login.login_manager' has no attribute 'user_loader'

由於我不需要數據庫,我認為示例中給出的用戶模式是不需要的。 但如果沒有它,它就會出錯。 我怎樣才能解決這個問題?

編輯:

根據以下建議,我添加了一個用戶 class,如下所示:

from flask_login import UserMixin, LoginManager, login_manager


class User(UserMixin):

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return int(self.id)

    def __repr__(self):
        return f"User('{self.username}', '{self.email}', '{self.powerlevel}')"

並將以下代碼添加到app.py文件中:

@login_manager.user_loader
    def load_user(user_id):
        # since the user_id is just the primary key of our user table, use it in the query for the user
        return User.query.get(int(user_id))

但它仍然顯示相同的錯誤。

我很確定如果沒有代表數據存儲的 class Flask-Login 將無法工作,因為在某些時候它需要訪問數據庫以了解用戶是否已經登錄以及其他身份驗證要求。

顯然,由於它沒有施加存儲限制,我認為您可以在沒有數據庫的情況下欺騙系統。

首先按照文檔https://flask-login.readthedocs.io/en/latest/ 中的說明創建用戶 class

像這樣定義一個 class - 所有這些方法都是必要的。

class User:
    def is_authenticated():
        ...
    def is_active():
        ...
    def is_anonymous():
        ...
    def get_id():
        ...

創建一個具有此用戶類型的全局變量並登錄用戶並執行其他任何操作。 您不一定需要此 class 代表信息的數據庫。

如果您在評論中理解,請告訴我。 樂意效勞:)

你得到這個答案了嗎,如何在沒有 db 的情況下實現 user_loader()

app.py 你會得到這個:

from flask_login import UserMixin, login_user, LoginManager, login_required, current_user, logout_user

app = Flask(__name__)

login_manager = LoginManager()
login_manager.init_app(app) #defined above app=Flask(__name__)
login_manager.login_view = 'login' #logged out users will be redirected to this route if attempting to view a route that requires login

@login_manager.user_loader
def load_user(id):
# This sets the callback for reloading a user from the session.
# The function you set should take a user ID and return a user object, or None if the user does not exist.
# id is str or int if the keys in data.USERS are str or int 
# "123123" or 123123 (see next section)
try:
    return data.USERS.get(str(id))
except:
    return None

@app.route("/", methods=["GET","POST"])
def login():
   if request.method == "POST":
       if request.form["login"]:
           id = request.form["id"]
           password = request.form["password"]
           response = data.confirmUserLogin(id, password)
           if response["status"] == True:
               # login the user
               # Login user, You should pass the actual user object to this. 
               # If the user’s is_active property is False, they will not be logged in unless force is True
               login_user(data.USERS[id])
               flash(response["message"])
               return redirect(url_for('index'))
           else:
               flash(response["message"])
               return redirect(url_for('login'))
    
    elif request.method == "GET":
        return render_template("login.html")

數據.py:

#you can use: class User(Usermixin)
"""
UserMixin pre-defines these attributes for your User class:
def is_authenticated():
    ...
def is_active():
    ...
def is_anonymous():
    ...
def get_id():
    ...
"""
# or you can just define these attributes yourself
class User():
    def __init__(self, id, username, active=True):
        self.id = id
        self.username = username
        self.active = active

    def is_active(self):
        # Here you should write whatever the code is
        # that checks the database if your user is active
        # return self.active
        # for demo i just return True
        return True 
    
    def is_authenticated(self):
        # for demo i just return True
        return True

    def get_id(self):
        # if you do not use Usermixin, this is important
        # user_loader load_user(id) uses this get_id attribute to load the id
        return self.id

# create local database of sample users
# Key are user id's : Value are User objects
USERS = {
    "123123": User("123123", "user1"),
    "456456": User("456456", "user2"),
    "789789": User("789789", "user3", False),
}

def confirmUserLogin(id, password):
    # check local db USERS for the id
    if USERS.get(sso):
        # get the user object (key's value)
        user = USERS.get(id)
        # check password
        if user.password == password:
            # entered password matches database password
            response = {"status":True, "message":"Login Successfull!"}
            return response
        else:
            # entered password DOES NOT match database password
            response = {"status":False, "message":"Wrong password, please try again."}
            return response
    else:
        # user does not exist
        response = {"status":False, "message":"User does not exist, please try again."}
        return response

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM