簡體   English   中英

對於 REST API,我可以使用 flask-login 提供的身份驗證機制,還是必須明確使用基於令牌的身份驗證,如 JWT?

[英]For a REST API, can I use authentication mechanism provided by flask-login or do I explicitly have to use token based authentication like JWT?

規格:我正在使用 PyQt5 在 Python 中編寫桌面應用程序。 我的應用程序通過提供 RESTful 路由的 Flask API 與遠程數據庫通信。 Flask API 和數據庫位於同一台服務器上。 在客戶端,我使用來自 Python 的Requests模塊。 我必須在我的應用程序中實現用戶身份驗證和授權系統。 目前,我正在使用燒瓶登錄。

@app.route("/login", methods=['POST'])
def login():
    user = User.query.filter_by(email = request.form["email"]).first()
    if user and check_password():
       flask_login.login_user(user, remember=request.form['remember'])
       return Response(status=201)
    else:
        return Response(status=401)

在上面的代碼中,我正在檢查用戶是否存在並且散列密碼是否匹配。 如果是這樣,flask_login 將自動登錄用戶並發送回一個cookie作為響應,我可以將其用於 session 管理和其他東西。

我的問題:我到處讀到基於令牌的身份驗證系統用於保護 API。 但是,我目前的方法有什么問題嗎? 這不是實現身份驗證的常規方式嗎? 此外,它在任何意義上都比基於令牌的系統更不安全嗎?

您的問題的答案不是直截了當的,但簡而言之,這可能是一般保護 API 的不好方法。 但是,如果這是您所熟悉的,那么您可能會以這種方式僥幸逃脫,因為它們並不是為什么這實際上不起作用的“技術”原因。

API 通常希望每次請求都將訪問憑證/令牌發送到 API。 這類似於 web 服務器(Flask)直接返回 html/js 代碼時請求的身份驗證方式。

然而,不同之處在於客戶端用於提交身份驗證證明的機制。 在后端服務前端代碼的典型應用程序中,cookies 用於存儲 session 信息,這些 cookies 由客戶端(瀏覽器)自動發送到后端。

在您的情況下,Flask 登錄正在查看這些 cookies 並驗證它們的真實性,並根據存儲在服務器上的 session 中的信息確定是哪個用戶提出了請求。

您提到您的客戶端是使用 Python 請求庫的桌面應用程序,因此如果您想繼續使用身份驗證方法,您需要對桌面客戶端進行編程以使用requests.Session ZA8CFDE6331BD59EB2AC96F8166666F811發送請求。 這基本上包裝了您的請求並為您存儲 cookies。 To do this you make an initial request to login with the request.Session object, and then all subsequent requests would automatically send the cookies and your Flask app would see that you're desktop app is logged in. Check out the docs for more info .

然而,使用 API,Flask web 服務器不會直接向客戶端提供前端代碼。 事實上,API 不應該關心客戶端是否有前端。 對於所有 API 知道客戶端可能是另一個腳本或在終端中運行curl命令的用戶等。重要的是,客戶端可能有也可能沒有任何“cookies”的概念。 所以 API 需要一種方法來驗證進來的請求是否被授權。

就像 cookies 需要隨每個請求一起發送一樣,API 需要隨每個請求發送一些內容,上面寫着“嘿服務器,我是一個請求,我已獲得授權。”

顯而易見的解決方案是在每個請求中發送用戶名和密碼。 這個解決方案非常基本,被恰當地稱為基本身份驗證。 顯然這里存在安全問題,但如果 http 流量被加密 (https) 在客戶端是運行在從安全文件中讀取密碼的安全盒上的進程的情況下,基本身份驗證可能沒問題。

Python 請求模塊在以下方面對此提供了支持: 鏈接到文檔就像發出這樣的請求一樣簡單:

requests.get('https://api.github.com/user', auth=('user', 'pass'))

然后在 Flask 后端

@app.route(...)
def some_route():
  username = request.authorization.username
  password = request.authorization.password
  # check to make sure username/password is okay
  # could abstract this code as a decorator and apply it to multiple routes
  # that you want protected by basic auth

還有Flask-BasicAuth模塊似乎使 Flask 接受基本身份驗證變得超級容易,盡管我從未使用過它。

但是,在客戶端不能被認為是超級安全的情況下,比如前端 web 應用程序,作為開發人員,您可能不想將用戶名和密碼直接存儲在瀏覽器中,並且可能有人只是查看本地存儲等並查看用戶憑據。

基於令牌的身份驗證是另一個更安全的選項,基本上客戶端將用戶名/密碼憑據發送到后端一次,並將它們交換為令牌。 然后,該令牌隨客戶端發出的每個請求一起發送。 在后端,web 服務器可以驗證令牌的真實性並從中提取身份。 令牌可以通過 HTTP header 或通過 url 查詢字符串發送。 IE www.myapi.com/some-end-point?token=12345678

然后,如果令牌被泄露,用戶可以使用相同的用戶名/密碼來獲取另一個令牌,並且舊令牌可能會過期。

如果您想使用令牌基礎身份驗證方法,請查看 JSON Web 令牌 (JWT),特別是在以下Flask插件中:

暫無
暫無

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

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