介紹
驗證是在登錄請求期間驗證使用者身份的過程。在驗證過程中,使用者提交他們的憑證,如用戶名和密碼。然後,應用程序將這些登錄憑證與存儲的數據庫項目進行匹配。如果匹配成功,應用程序將授予使用者訪問系統的權限。
將登錄憑證存儲在像MySQL或PostgreSQL這樣的關聯式數據庫中,並且沒有緩存機制,仍然是一種常見且實用的方法,但其存在以下限制:
-
過度加載數據庫。每次使用者提交登錄請求時,應用程序必須從數據庫表中進行一次往返到數據庫服務器以驗證使用者的憑證。由於數據庫可能還需要處理其他讀/寫請求,整個過程會過載數據庫並使其變慢。
-
傳統基於磁盤的數據庫存在可擴展性問題。當您的應用程序每秒接收到數千個請求時,基於磁盤的數據庫的性能不佳。
為了克服上述挑戰,您可以使用Redis來緩存用戶的登錄憑據,這樣您的應用程序就不必在每次登錄請求中與後端數據庫進行通信。Redis是一個使用計算機的RAM來存儲鍵值對數據的最受歡迎的超高速數據存儲庫之一。在本指南中,您將在Ubuntu 22.04服務器上使用Redis數據庫來加快Python/MySQL應用程序的會話處理速度。
前提條件
在開始本教程之前,您需要設置以下內容:
- 創建一個非root的sudo用戶。
-
切換至新的
sudo
使用者帳號並安裝:
步驟1 — 安裝Redis和MySQL的Python資料庫驅動程式
此應用程式將使用者的憑證,例如姓名和密碼,永久儲存於MySQL資料庫伺服器中。當使用者登入應用程式時,Python腳本會查詢MySQL資料庫並將詳細資料與儲存的值進行比對。然後,Python腳本會將使用者的登入憑證快取到Redis資料庫中,以供未來的其他請求使用。為了完成這個邏輯,您的Python腳本需要使用資料庫驅動程式(Python模組)來與MySQL和Redis伺服器進行通訊。按照以下步驟安裝這些驅動程式:
- 更新您的套件資訊索引並執行以下命令來安裝
python3-pip
,這是一個Python套件管理程式,可讓您安裝Python標準庫之外的額外模組。
- 安裝Python的MySQL驅動程式:
- 安裝Python的Redis驅動程式:
在安裝了與MySQL和Redis通訊所需的驅動程式之後,請繼續下一步並初始化一個MySQL資料庫。
第2步 — 設置一個範例MySQL資料庫
在本指南中,您需要一個MySQL資料表。在生產環境中,您可以擁有數十個用於處理其他請求的資料表。通過執行以下命令來設置資料庫並創建資料表:
-
以
root
用户登录到MySQL数据库服务器: -
在提示时输入您的MySQL服务器的
root
密码,然后按ENTER
键继续。然后运行以下命令来创建一个示例company
数据库和一个company_user
账户。将example-mysql-password
替换为强密码:
-
确保您收到以下输出以确认之前的命令已成功运行:
-
切換到新的
company
資料庫: -
通過驗證以下輸出來確認您已連接到新的資料庫:
-
創建一個
system_users
表。user_id
列用作唯一識別每個用戶的PRIMARY KEY
。username
和password
列是用戶必須提交的登錄憑據,以便登錄應用程序。first_name
和last_name
列存儲用戶的名字: -
通過驗證以下輸出,確保您已創建新表:
-
使用MySQL内置的
MD5(...)
函数对密码进行哈希处理,向system_users
表中填充示例数据: -
验证以下输出:
-
查询
system_users
表以确保数据已填充: -
驗證以下輸出:
-
從MySQL資料庫登出:
您現在已經設定了適合您應用程式的正確MySQL資料庫。在下一個步驟中,您將建立一個與您的範例資料庫通信的Python模組。
第3步 – 為Python創建一個中央MySQL Gateway模組
在編寫任何Python項目時,您應該為每個任務創建一個單獨的模組,以促進代碼可重用性。在這一步中,您將設置一個中央模組,該模組允許您從Python腳本連接和查詢MySQL資料庫。請按照以下步驟進行:
-
創建一個
project
目錄。此目錄將您的Python原始碼文件與其他系統文件分開: -
切換到新的
project
目錄: -
使用
nano
文本編輯器打開新的mysql_db.py
文件。此文件用於托管與MySQL數據庫通信的Python模塊: -
將以下資訊輸入到
mysql_db.py
檔案中。將example-mysql-password
替換為company_user
帳戶的正確MySQL密碼:~/project/mysql_db.py -
保存並關閉
mysql_db.py
檔案。
mysql_db.py
模組檔案中有一個類別(MysqlDb:
),其中包含兩個方法:
– db_con(self):
,連接到之前創建的範例 company
資料庫並使用 return mysql_con
語句返回可重複使用的 MySQL 連接。
– query(self, username, password):
,一個接受 username
和 password
參數的方法,並查詢 system_users
表以查找是否存在匹配的用戶。條件語句 if row_count < 1: ... else: return result[1]
如果在表中找不到用戶則返回布林值 False
,如果應用程式找到匹配的用戶則返回用戶的密碼(result[1]
)
MySQL 模組準備好後,請按照下一個步驟來設置一個類似的能夠與 Redis 鍵值存儲進行通信的 Redis 模組。
第 4 步-創建 Python 的中央 Redis 模組
在這一步中,您將編寫一個連接到 Redis 伺服器的模組。執行以下步驟:
-
打開一個新的
redis_db.py
文件: -
將以下資訊輸入到
redis_db.py
檔案中。將example-redis-password
替換為Redis伺服器的正確密碼:~/project/redis_db.py -
保存並關閉
redis_db.py
文件。
-
上述文件有一個類(
RedisDb:
)。 -
在這個類下,
db_con(self):
方法使用提供的憑證連接到Redis服務器,並使用return redis_con
語句返回可重複使用的連接。
設置完Redis類後,請在下一步中創建項目的主文件。
步驟5 – 創建應用程序的入口點
每個Python應用程序都必須有一個入口點或主文件,在應用程序運行時執行。在這個文件中,您將創建一段代碼,為已驗證的用戶顯示當前服務器的時間。該文件使用您創建的自定義MySQL和Redis模塊來驗證用戶。按照以下步驟創建該文件:
-
打開一個新的
index.py
檔案: -
輸入以下資訊到
index.py
檔案:~/project/index.py -
儲存並關閉
index.py
檔案。
-
在
index.py
檔案中的import...
區段中加入以下模組到您的專案中:-
utf_8
、base64
、md5
和json
,文字編碼和格式化模組。 -
http.server
、HTTPStatus
和socketserver
,網頁伺服器模組。 -
datetime
,時間/日期模組。 -
mysql_db
和redis_db
,您之前建立的自訂模組,用於存取MySQL和Redis伺服器。
-
-
HttpHandler(http.server.SimpleHTTPRequestHandler):
是用于HTTP服务器的处理程序类。在该类下,do_GET(self):
方法用于处理HTTP GET 请求,并显示经过身份验证的用户的系统日期/时间。 -
在
if ... : else: ...
逻辑中,Python脚本运行逻辑if redis_client.exists(auth_user):
语句来检查用户凭据是否存在于Redis服务器中。如果用户详细信息存在且Redis中存储的密码与用户提交的密码不匹配,应用程序将返回{"error": "Invalid username/password."}
错误。
如果Redis服务器中不存在用户详细信息,则应用程序使用mysql_resp = mysql_server.query(auth_user, auth_password)
语句查询MySQL数据库服务器。如果用户提供的密码与数据库中存储的值不匹配,则应用程序返回{"error": "无效的用户名/密码。"}
错误。否则,应用程序使用redis_client.set(auth_user, mysql_resp)
语句将用户的详细信息缓存到Redis服务器中。
-
在所有情况下,当用户的凭证与Redis/MySQL的详细信息匹配时,应用程序使用
{"time": current_time, ...}
语句显示系统的当前日期/时间。输出中的authorized by
条目允许您查看应用程序中验证用户的数据库服务器。
您现在已经设置好了应用程序的主文件。下一步,您将测试该应用程序。
第 6 步 — 测试应用程序
在此步骤中,您将运行应用程序以查看 Redis 缓存机制是否正常工作。执行以下命令来测试应用程序:
-
使用以下
python3
命令运行应用程序: -
确保应用程序的自定义网络服务器正在运行:
-
在新的終端視窗中建立另一個
SSH
連線到您的伺服器,並執行以下curl
命令,使用john_doe
的憑證發送四個 GET 請求。在http://localhost:8080/
URL 的末尾附加[1-4]
以一個命令發送四個請求: -
驗證以下輸出。MySQL 伺服器僅服務第一個認證請求。然後,Redis 資料庫處理接下來的三個請求。
您的應用程式邏輯已正常運作。
結論
在本指南中,您建立了一個使用Redis服務器緩存用戶登錄凭據的Python應用程序。Redis是一個高可用性和可擴展性的數據庫服務器,可以執行成千上萬的事務每秒。通過在應用程序中使用Redis緩存機制,您可以大大減少後端數據庫服務器的流量。要了解更多關於Redis應用的信息,請參閱我們的Redis教程。